A JSON Web Token (JWT) looks like a long random string, but it is only three pieces of data glued together with dots. The first piece says how the token was built. The second piece is the claims - who it is for, when it expires, and whatever else the issuer stuffed in. The third piece is a signature that a trusted server can check. This guide walks through each part, the claims you will see every day, and the difference between reading a token and trusting it. When you want to inspect a real token, paste it into the JWT Decoder - it runs in your browser and never uploads the value.
Quick answer
A JWT is header.payload.signature. The header and payload are Base64URL-encoded JSON. The header usually has alg and typ. The payload holds claims such as sub, iat, and exp plus any custom fields. The signature is the third segment. Decoding shows those JSON objects. It does not prove the token is genuine - verification needs the secret or public key on a trusted server.
Three parts joined by dots
RFC 7519 defines a compact JWT as three Base64URL segments separated by a period. There is no extra wrapper, no JSON around the outside, and usually no padding equals signs. If you split on . you always get three strings, even when the last one is empty (the unsecured alg none form).
- Header: metadata about the token, almost always JSON with alg and typ.
- Payload: the claims. This is the data APIs actually read.
- Signature: a cryptographic tag over the header and payload. This tool and this article treat it as opaque bytes.
Anyone who can write JSON can mint a header and a payload and Base64URL-encode them. That is why the first two parts are public. Anyone who intercepts a JWT can read those claims. Confidential data does not belong in a JWT unless you also encrypt it (JWE), which is a different format.
The header
The header tells verifiers how to treat the token. It is a small JSON object. After Base64URL-decoding the first segment you typically see:
- alg - the algorithm used to sign (or none). Common values: HS256 (HMAC with a shared secret), RS256 or ES256 (asymmetric keys).
- typ - usually JWT. Some issuers omit it.
- kid - an optional key id so a server can pick the right public key from a JWKS set.
- cty - content type, rare, used when the payload is a nested JWT.
The dangerous header field is alg. A decoder will show whatever the token claims. A naive verifier that honors alg none, or that lets an attacker switch RS256 to HS256 and sign with the public key as if it were an HMAC secret, will accept forged tokens. That is a server bug, not something a browser decoder can fix. Read alg as a hint, never as proof.
The payload (claims)
The payload is another JSON object. JWT specs split claims into registered names (a small shared vocabulary) and private or public custom names that your app defines. Timestamps are NumericDate values: seconds since 1970-01-01 UTC, not milliseconds.
Registered claims you will see often
- iss - issuer. Who minted the token (a URL or an auth-server name).
- sub - subject. The user or service the token is about.
- aud - audience. The API or app that should accept it. Can be a string or an array.
- exp - expiration. Reject the token after this Unix time.
- nbf - not before. Reject the token before this Unix time.
- iat - issued at. When the issuer created it.
- jti - JWT id. A unique id used to revoke or deduplicate tokens.
Custom claims
Anything else is application data: name, email, role, scope, tenant, or a permissions array. These fields are convenient for APIs, and they are also trivial to forge if you only decode. A role: admin claim in a token you pasted into a decoder means the issuer (or an attacker) wrote that string. It is not a permission grant until a backend verifies the signature and checks iss, aud, and exp.
The signature
The third segment is not JSON. For HS256 it is an HMAC-SHA256 over the ASCII string header.payload using a shared secret. For RS256 or ES256 it is an asymmetric signature over the same input. The decoder shows the raw Base64URL text so you can compare tokens; it never recomputes or checks that tag. Verification needs the secret or the issuer's public key, and it must happen on a machine you trust.
Decode is not verify
Reading header and payload JSON only answers "what does this token claim?" A server that accepts the token must still verify the signature, reject the wrong alg, check exp / nbf / iat, and match iss and aud. The JWT Decoder is for inspection and debugging, not for login.
Base64URL, not ordinary Base64
JWT header and payload use Base64URL (RFC 4648): the same 6-bit encoding as Base64, but + becomes -, / becomes _, and the trailing = padding is often dropped. That keeps tokens safe inside query strings and headers. If you paste a JWT segment into a generic Base64 tool, restore URL characters first or the JSON will not decode. The Base64 Encoder / Decoder is for ordinary Base64; the JWT tool already applies the URL alphabet.
Worked example
The classic demo token used in JWT docs decodes to a tiny header and payload. After splitting on dots and Base64URL-decoding the first two parts you get:
- Header JSON: {"alg":"HS256","typ":"JWT"}
- Payload JSON: {"sub":"1234567890","name":"John Doe","iat":1516239022}
- iat 1516239022 is 2018-01-18 01:30:22 UTC - the token is years past any real expiry if one had been set.
- The third segment is the HMAC signature. Looking at it does not tell you whether the secret was correct.
A Bearer prefix is not part of the JWT. Authorization: Bearer eyJ... is an HTTP header convention. Strip Bearer and the following space, then decode the remaining three segments. The ToolsMinify decoder does that for you.
What you can read vs what a server must check
Use a decoder when you are debugging. Use a verifier when you are authorizing.
- You can read alg, typ, and kid to see which key the issuer intended.
- You can read sub, email, or role to understand a failing request.
- You can compare exp and iat to a clock to see if a token is stale.
- A server must verify the signature with the right key and the right algorithm.
- A server must reject tokens with the wrong iss or aud, and tokens that are not yet valid or already expired.
- A server must treat every claim as untrusted until those checks pass.
Common mistakes
- Trusting claims from a decoder. Anyone can assemble header.payload and leave a junk signature.
- Accepting alg none or letting the token pick the verify algorithm.
- Putting passwords, session secrets, or personal data in the payload. The payload is readable by anyone who has the token.
- Pasting production tokens into a random website. Prefer a client-side decoder so the token never leaves the machine.
- Confusing this format with encrypted JWTs (JWE). A compact JWE has five segments, not three.
Frequently asked questions
Is a JWT encrypted?
A standard signed JWT (JWS) is not encrypted. Header and payload are only encoded. Anyone with the token can read the claims. Encrypted tokens use JWE and look different. If you can paste a token into a decoder and see JSON, it was not confidential.
Why does the decoder refuse to verify the signature?
Verification needs a secret or a private-key holder's public key. Shipping those into a public web page would be unsafe, and a green "valid" badge on an untrusted site would train people to trust the wrong check. Decode locally; verify on your API.
What does alg none mean?
It means the issuer (or an attacker) marked the token as unsecured. The third segment is empty. A decoder can still show the header and payload. A production API should reject alg none unless you have a very explicit, local reason to accept unsigned tokens.
Are exp and iat in milliseconds?
No. JWT NumericDate values are seconds since the Unix epoch. If a claim looks like 1.7e12 you are probably looking at JavaScript Date.now() milliseconds by mistake.
Can I rebuild a token after I edit the payload?
You can re-encode JSON to Base64URL and join three segments, but the old signature will no longer match. Without the issuer's secret or private key the new token is forged. That is expected. Decoders are for reading, not for minting production tokens.
Where should I inspect a token safely?
Use a page that decodes in the browser and does not upload the string. The JWT Decoder on ToolsMinify does that. For the click-by-click walkthrough see How to Use JWT Decoder.
Inspect a token in your browser
Paste a JWT to see header, payload, and signature as readable sections. Nothing is uploaded:
- JWT Decoder - split a token, pretty-print header and payload JSON, copy each part.
- How to Use JWT Decoder - step-by-step guide for the same tool.
- Base64 Encoder / Decoder - ordinary Base64, not the JWT URL alphabet.
- Hash Generator - SHA-256 checksums in the browser. Not JWT signing.
- All developer tools - the full category index.
Decode a JWT - free
Open the JWT Decoder, paste a token, and read the header and claims. The signature is shown as-is and is never verified. Everything runs in your browser.