What this does
Splits a JSON Web Token on its dots, base64url-decodes the first two parts
and pretty-prints them as JSON, alongside a summary strip: algorithm, type,
issued-at and expiry. Expiry shows a real date plus the time left —
in 43 min, in 6 h, in 12 d — and turns
red once the token is past its exp. The signature is shown
verbatim and left alone. All of it happens in the page, so pasting a
production access token here does not leak it.
Does this verify the JWT signature?
No. It decodes, it does not validate. The third segment is
displayed as an opaque string and never checked, because verifying it needs
the issuer's HMAC secret or public key and this tool asks for neither. A
token you edited by hand decodes just as happily as a real one, so treat the
output as "what the token claims". Do the real verification in your backend
with a JOSE library against the issuer's JWKS endpoint, checking
alg, iss, aud and expiry there.
What are the three parts of a JWT?
header.payload.signature, each base64url-encoded: the URL-safe
alphabet, with - and _ for + and
/, and = padding usually stripped (the decoder puts
it back). The standard sample token decodes to:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 → {"alg":"HS256","typ":"JWT"}
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6… → {"sub":"1234567890","name":"Jane","iat":1516239022}
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c (signature, not verified) Is the payload encrypted?
No, and this is the most common misunderstanding about JWTs. Base64url is encoding, not encryption — anyone holding the token reads every claim in it, exactly as this page just did, with no key involved. Signing protects against tampering, not against reading. Never put a password, an API key, a card number or anything you would not print in a log into a payload. If the content must genuinely be hidden you need JWE, which has five segments rather than three and is rejected here as malformed.
What do the standard claims mean?
iss— issuer, who minted the token.sub— subject, usually the user ID the token speaks for.aud— audience, the API meant to accept it. Rejecting tokens minted for someone else is your job, not a library default.exp,nbf,iat— expiry, not-before and issued-at, in Unix seconds. The strip showsiatandexp;nbfis in the payload JSON.jti— unique ID, for replay protection and revocation lists.
Everything else is a custom claim: scopes, roles, tenant IDs, whatever the issuer chose to include.
How do I debug a token my API is rejecting?
- Paste the raw token — no
Bearerprefix, no quotes, no stray line breaks. - Check Expires first. Most rejections are an expired token; clock skew between machines explains many of the rest.
- Compare
issandaudagainst what your API accepts — a token from the wrong tenant or environment is the next most common cause. - Look at
alg. Anone, orHS256where you expectedRS256, means a forged or misconfigured token; a correct verifier pins the algorithm rather than trusting the header. - Then check the scopes or roles claim the endpoint requires.
Why does it say the token is malformed?
Three errors are possible. "A JWT has three parts separated by dots" means the split produced the wrong number of segments — usually a truncated copy or a JWE. The header and payload errors mean a segment decoded but was not valid JSON: mangled in transit, or only partly pasted. Related: Base64, JSON formatter, and Unix timestamp converter for date claims the strip omits.