We use cookies

We use cookies and similar technologies to enhance your browsing experience, analyze site traffic, and personalize content and ads. By clicking "Accept", you consent to our use of cookies. Learn more in our Privacy Policy.

JWT

JWT Decoder

by Cosmovex

Paste a JWT token above to decode it

Free JWT Decoder & Verifier

Decode JWT tokens to view header and payload claims, check expiry status, verify HS256 signatures. No signup required.

More Developer Tools

View all tools →
64
Base64
Encode & decode Base64 strings
%20
URL Encoder
Encode & decode URLs
&
HTML Entity Encoder
Encode & decode HTML entities
\
String Escaper / Unescaper
Escape & unescape text strings
{ }
JSON Formatter
Format, validate & explore JSON
YAML Formatter
Lint, format & convert YAML
</>
XML Formatter
Beautify & validate XML
CSV Formatter
View & format CSV tables

A JSON Web Token (JWT) is a compact, URL-safe string used to carry identity and authorization data between services. It looks like one long blob, but it's actually three Base64URL-encoded parts joined by dots: a header, a payload, and a signature. This tool splits the token apart and decodes the header and payload into readable JSON so you can see exactly what claims a token carries.

Paste a token and you immediately get the decoded header and payload, plus a plain-language breakdown of the standard claims like exp, iat, iss, and sub, including whether the token has expired. Everything runs in your browser, so the token you paste never leaves your machine and is never sent to a server. That matters here because access tokens are credentials, and pasting a live one into a remote site is a real risk.

How it works

A JWT is three parts separated by dots: header.payload.signature. The header and payload are JSON objects, each Base64URL-encoded; the signature is a cryptographic check over the first two parts.

This tool does the following:

  • Splits the token on the two dots into header, payload, and signature.
  • Base64URL-decodes the header and payload back into JSON and pretty-prints them.
  • Highlights the standard claims so you don't have to read raw timestamps. It converts exp, iat, and nbf from Unix epoch seconds into human-readable dates, and flags whether the token is currently expired or not yet valid.
  • Shows the algorithm from the header's alg field (for example HS256 or RS256) and the key id kid if present.

Decoding is not the same as verifying. This tool reads the contents but does not check the signature, because that requires the issuer's secret or public key. Treat the decoded payload as untrusted input until something with the key has verified it.

A worked example

Take this token (line-wrapped here for readability; paste it as one line):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjJ9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The decoder splits it and shows:

// header
{ "alg": "HS256", "typ": "JWT" }

// payload
{
  "sub": "1234567890",
  "name": "Jane Doe",
  "iat": 1516239022,
  "exp": 1516242622
}

From this you can read it directly: the subject (sub) is user 1234567890, the token was issued (iat) and expires (exp) one hour later, and it's signed with HS256. The decoder converts those epoch numbers to dates and tells you the token expired long ago. Notice that name is sitting in plain readable JSON, which is the whole point of the next gotcha.

Common use cases

  • Debugging auth failures. A 401 from an API often comes down to an expired token or a wrong audience. Decode it and check exp and aud before blaming the network.
  • Confirming what your backend signed. When building a login flow, paste the issued token to verify the claims you intended (sub, roles, tenant id) actually made it in.
  • Reading third-party tokens. OAuth providers and identity platforms hand back ID tokens; decoding shows which scopes and profile fields are present.
  • Inspecting kid and alg. When rotating keys or setting up JWKS verification, the header's kid tells you which public key the verifier needs.
  • Spotting clock-skew problems. If nbf (not before) is in the future relative to a server's clock, requests get rejected even though the token "looks" fine.
  • Teaching and code review. Showing a teammate what's actually inside a token is faster than explaining the spec.

Tips and gotchas

  • The payload is not encrypted. Base64URL is encoding, not encryption. Anyone holding the token can read every claim. Never put passwords, secrets, or sensitive personal data in a JWT payload.
  • A valid decode does not mean a valid token. This tool reads the contents; it does not verify the signature. A token with a tampered payload still decodes cleanly. Always verify the signature server-side with the correct key.
  • exp and iat are seconds, not milliseconds. A common bug is comparing exp against Date.now() (which is milliseconds). Multiply exp by 1000 first.
  • alg: none is a red flag. Some attacks strip the signature and set the algorithm to none. Production verifiers should reject it outright.
  • Padding differs from plain Base64. JWT uses Base64URL (- and _ instead of + and /, no = padding), which is why generic Base64 tools sometimes choke on the parts.

Standard claims, briefly

The JWT spec defines a small set of registered claims with reserved meanings. You'll see these constantly:

  • iss (issuer) — who created and signed the token, often a URL.
  • sub (subject) — who the token is about, typically a user id.
  • aud (audience) — who the token is intended for; a verifier should reject tokens not meant for it.
  • exp (expiration) — Unix time after which the token must be rejected.
  • nbf (not before) — Unix time before which the token is not yet valid.
  • iat (issued at) — Unix time the token was created.
  • jti (JWT id) — a unique identifier, useful for revocation or replay protection.

Everything else is a custom (private) claim: name, email, roles, tenant_id, and so on. The decoder shows registered and custom claims together, but only the registered ones carry spec-defined behavior that verifiers act on.

Tips

  • Decode shows contents; it never proves the token is genuine. Verify the signature with the issuer's key before trusting any claim.
  • Remember exp/iat/nbf are in seconds. Multiply by 1000 before comparing to JavaScript's Date.now().
  • Never store sensitive data in a payload. It's only Base64URL-encoded and anyone with the token can read it.
  • Check the aud claim when debugging 401s. A token signed for a different audience is valid but rejected by your service.
  • If you see alg: none or an unexpected algorithm, treat the token as suspect and reject it in production.
  • Since this runs locally, you can safely paste real tokens to debug. Still revoke any token you've shared in a chat or ticket.

How to use JWT Decoder

  1. 1Paste your JWT (the xxxxx.yyyyy.zzzzz string).
  2. 2The header and payload are decoded and pretty-printed.
  3. 3Review claims such as exp, iat, iss, and sub.
  4. 4Nothing is transmitted — decoding is local and safe.

Frequently asked questions

Does decoding a JWT verify that it's valid?

No. Decoding only reads the Base64URL-encoded header and payload. Verifying validity means checking the signature against the issuer's secret or public key and confirming claims like exp and aud, which requires the key this tool doesn't have.

Is the JWT payload encrypted?

No. A standard JWT (JWS) payload is Base64URL-encoded, not encrypted. Anyone with the token can read every claim, so never put secrets or sensitive personal data in it. If you need encryption, that's a separate format called JWE.

Is my token sent anywhere when I paste it here?

No. The decoding happens entirely in your browser. The token is never uploaded to a server, which is why it's safe to inspect a real, live token.

Why does my token show as expired when it just worked?

Check whether you're comparing exp (which is in Unix seconds) against a millisecond clock, or whether server and client clocks are out of sync. A small clock skew combined with a short lifetime can make a fresh token look expired.

What's the difference between iat, nbf, and exp?

iat is when the token was issued, nbf is the earliest time it's considered valid, and exp is when it stops being valid. All three are Unix timestamps in seconds. A token is only usable in the window between nbf and exp.

Why won't a regular Base64 decoder read the parts?

JWT uses Base64URL, which replaces + and / with - and _ and drops the = padding. Generic Base64 tools may fail or produce garbage. This decoder handles Base64URL correctly.

Can I decode just the header or payload separately?

Yes. The header and payload are independent Base64URL JSON segments. If you only have one segment (the part before or between the dots), you can decode it on its own; the signature isn't needed to read either one.

What does the kid field in the header mean?

kid is the key id. When an issuer uses multiple signing keys, kid tells a verifier which public key (usually from a JWKS endpoint) to use to check the signature. It's informational here and doesn't affect decoding.

← All toolsRead our guides →