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 Decoder

What 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 example HS256 or RS256, and often typ and a key ID in kid.
  • 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

ClaimMeaning
issIssuer: who created the token
subSubject: the user or client the token is about
audAudience: the service the token is meant for
expExpiration time
nbfNot before: the token is invalid before this time
iatIssued at
jtiA 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

  1. Paste the token into the JSON Web Token box. If you copied it from an Authorization header, remove the Bearer prefix first.
  2. Select Decode JWT. Decoding runs in your browser, and the token is not sent to a server.
  3. Read the result. A "Signature not verified" label appears above the Header and Payload, which are shown as formatted JSON.
  4. If the payload has an exp claim, an Expires line shows that time in ISO 8601 format in UTC. Compare it with the current UTC time. Other time claims such as iat and nbf stay as raw numbers.
  5. 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 kid header tells you which key to use.
  • Accepting only the algorithms you expect, and rejecting alg set to none.
  • Checking exp and nbf against the current time.
  • Checking that iss and aud match 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 exp as milliseconds. JavaScript's Date.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.

Try the free JWT Decoder

Put this guide into practice in your browser.

Open the JWT Decoder