Quick answer: A JSON Web Token is three Base64url-encoded parts joined by dots, so you can decode the header and payload without any key and read them as JSON. Decoding only shows what the token claims. It does not prove the token is genuine; only signature verification with the right key does that.
Try the free JWT Decoder
Free, no sign-up, and built by the author of this guide.
Open the JWT DecoderWhat is inside a JWT
JWTs are defined in RFC 7519. Most tokens you meet are signed tokens in the compact form of JSON Web Signature (RFC 7515), which looks like header.payload.signature:
- Header: JSON that names the signing algorithm in
alg, for exampleHS256orRS256, and oftentypand a key ID inkid. - Payload: JSON with the claims, such as who the token is for and when it expires.
- Signature: bytes computed over the first two parts with a secret or private key.
Each part uses the URL-safe Base64 alphabet from RFC 4648 section 5, with - and _ instead of + and /, and the = padding removed. That encoding is not encryption, so anyone holding the token can read the payload. Encrypted tokens (JWE) have five parts instead of three, and their payload cannot be read without the key.
Registered claims you will see
| Claim | Meaning |
|---|---|
iss | Issuer: who created the token |
sub | Subject: the user or client the token is about |
aud | Audience: the service the token is meant for |
exp | Expiration time |
nbf | Not before: the token is invalid before this time |
iat | Issued at |
jti | A unique token ID |
The time claims are NumericDate values: seconds since 1970-01-01T00:00:00Z, not milliseconds. Any other claim, such as role or email, is application-specific.
Worked example: decoding a real token
This token was signed with HS256 and a throwaway demo secret:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQyIiwibmFtZSI6IkphbmUgRG9lIiwicm9sZSI6ImVkaXRvciIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzY3MjI5MjAwfQ.-UEL9LNgdeLmTn9YryFQnUkv20NlAiamMu_-fraLfkM
Decoding the first part gives the header:
{
"alg": "HS256",
"typ": "JWT"
}Decoding the second part gives the payload:
{
"sub": "user-42",
"name": "Jane Doe",
"role": "editor",
"iat": 1767225600,
"exp": 1767229200
}iat 1767225600 is 2026-01-01T00:00:00Z and exp 1767229200 is exactly 3,600 seconds later, 2026-01-01T01:00:00Z, so this is a one-hour token. The decoder shows the expiry as 2026-01-01T01:00:00.000Z. Nothing in this output says whether the signature is valid. Change one character of the signature and the decoded header and payload stay exactly the same.
How to use the free JWT Decoder
- Paste the token into the JSON Web Token box. If you copied it from an
Authorizationheader, remove theBearerprefix first. - Select Decode JWT. Decoding runs in your browser, and the token is not sent to a server.
- Read the result. A "Signature not verified" label appears above the Header and Payload, which are shown as formatted JSON.
- If the payload has an
expclaim, an Expires line shows that time in ISO 8601 format in UTC. Compare it with the current UTC time. Other time claims such asiatandnbfstay as raw numbers. - If you see "Invalid JWT", the input has fewer than two dot-separated parts, or a part is not valid Base64url-encoded JSON. Check for missing characters or extra quotes.
The tool does not check the signature or validate claims, and it cannot read the encrypted payload of a five-part JWE token.
Decoding is not verifying
Anyone can create a token with any payload, encode it and attach a fake signature. A server that trusts decoded claims without checking the signature can be tricked into granting access. Proper verification, done in your application with a maintained JWT library, means:
- Checking the signature with the expected key or secret. For RS256 and other public-key algorithms, issuers often publish their public keys as a JSON Web Key Set (JWKS), and the
kidheader tells you which key to use. - Accepting only the algorithms you expect, and rejecting
algset tonone. - Checking
expandnbfagainst the current time. - Checking that
issandaudmatch your issuer and service.
RFC 8725, JSON Web Token Best Current Practices, covers these checks in more detail.
Common mistakes
- Treating a decoded token as trusted. Decode for debugging; verify before making any access decision.
- Putting secrets or personal data in the payload, assuming nobody can read it.
- Reading
expas milliseconds. JavaScript'sDate.now()returns milliseconds, so divide by 1,000 before comparing. - Ignoring clock differences between servers; libraries usually allow a small leeway for this.
- Pasting live production tokens into online tools that send them to a server.
Frequently asked questions
Can I decode a JWT without the secret key?+
Yes. The header and payload of a signed JWT are only Base64url-encoded, so anyone can decode them. The key is needed only to create or verify the signature.
Does decoding a JWT tell me it is valid?+
No. Decoding shows the claims but does not check the signature, issuer, audience or expiry. Your application must verify the token with a JWT library and the correct key.
Why does my JWT have five parts?+
A five-part token is an encrypted JWE token. Its payload is encrypted, so it cannot be read without the decryption key.
Is it safe to paste a JWT into an online decoder?+
Only if the decoding happens in your browser. A valid token can work like a password until it expires, so avoid tools that send it to a server, and prefer test tokens.
What is the difference between HS256 and RS256?+
HS256 signs with HMAC SHA-256 and one shared secret, so every service that verifies the token can also create tokens. RS256 signs with an RSA private key and verifies with the public key, so verifiers never hold the signing key. Both are defined in RFC 7518.