If you've worked with any modern API or logged into an app that uses "Bearer tokens," you've seen a JWT — a long string that looks like eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0In0.dGhpc2lzbm90YXJlYWxzaWduYXR1cmU. It looks encrypted. It isn't. Here's what's actually in there.
Three parts, separated by dots
Every JWT has exactly three sections, joined by periods: header.payload.signature. The first two are just JSON, encoded with Base64URL (a URL-safe variant of Base64) — not encrypted, not hashed, just encoded. Anyone can decode them, which is the first thing that surprises people: a JWT is readable by anyone who has it, unless the app specifically encrypts it on top (a separate, less common standard called JWE). Never put a password or a secret directly inside a JWT payload.
1. The header
A small JSON object naming the algorithm used to sign the token and its type, typically something like {"alg":"HS256","typ":"JWT"}. alg is the one to pay attention to — it tells you (and the server) what kind of signature to expect.
2. The payload
The actual data — usually called "claims." Some are standardized (sub for subject/user ID, exp for expiration timestamp, iat for issued-at), and apps can add whatever custom claims they need on top — roles, permissions, a session ID, whatever the API cares about.
3. The signature
This is the part that actually matters for security. It's a cryptographic signature over the header and payload together, generated with a secret (for HS256) or a private key (for RS256). It doesn't hide the payload — it proves the payload hasn't been tampered with since the server issued it. Change even one character of the payload and the signature no longer matches.
Decoding vs. verifying — these are different things
Decoding a JWT just means reading the header and payload — no secret needed, since it's plain Base64. Verifying a JWT means checking that the signature is actually valid, which requires the same secret or public key the token was signed with. A token can decode perfectly and still be a forgery if nobody checks the signature.
Using the tool
Our JWT Decoder does both. Paste a token and it'll show you the decoded header and payload immediately — no key required for that part. If you also want to confirm the token is genuine (not just readable), paste the signing secret (for HS256/HS384/HS512) or the PEM-formatted public key (for RS256/RS384/RS512) into the optional field, and it'll tell you whether the signature actually checks out. Nothing you paste — token or key — is stored; it's used for that one check and discarded.
Try it here: JWT Decoder.