Skip to content
Toolshelf

How to Decode a JWT

Decode a JSON Web Token into header and payload JSON, read exp and iat claims, and understand why decoding is not signature verification.

Decode the two JSON segments — leave the signature alone

A compact JWT is three Base64URL pieces separated by dots: header.payload.signature. To decode it, split on ., Base64URL-decode the first two segments, and parse each result as JSON. The third segment is a cryptographic signature. Reading it as text does not prove the token is authentic.

If you want that inspection without uploading a token, paste it into the JWT Decoder & Inspector. Decoding runs in your browser. The page will not mark a signature as verified.

What a compact JWT looks like

Most access tokens you copy from an Authorization: Bearer header use JWS compact serialization (RFC 7519). Three segments, no whitespace:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhY2N0LTEwNDIiLCJuYW1lIjoiUHJpeWEgU2hhaCIsImlzcyI6Imh0dHBzOi8vYXV0aC5leGFtcGxlLmNvbSIsImlhdCI6MTcxOTc5MjAwMCwiZXhwIjoxNzE5Nzk1NjAwfQ.bm90LWEtcmVhbC1zaWduYXR1cmU
Educational sample only. The signature is a placeholder and must not be treated as valid.

Step 1 — Split on dots

Count the dots. A typical signed JWT (JWS) has exactly two dots and three segments. A compact JWE (encrypted token) has five segments; you can read its header, but you cannot decrypt the payload without the key.

  • Segment 1 — JOSE header (alg, often typ)
  • Segment 2 — payload (claims)
  • Segment 3 — signature (integrity check, not JSON)

Step 2 — Base64URL-decode header and payload

JWT uses Base64URL (RFC 7515), not standard Base64. The alphabet replaces + with - and / with _, and padding = is usually omitted. Feeding a JWT segment into a generic Base64 decoder often fails for that reason.

After decoding, you should get JSON objects. Header for the sample above:

{
  "alg": "HS256",
  "typ": "JWT"
}

Step 3 — Read the payload claims

The payload is also a JSON object. Registered claim names are defined in RFC 7519. Applications add their own claims on top.

{
  "sub": "acct-1042",
  "name": "Priya Shah",
  "iss": "https://auth.example.com",
  "iat": 1719792000,
  "exp": 1719795600
}
ClaimMeaning
issIssuer — who created the token
subSubject — who the token is about
audAudience — which API or app should accept it
expExpiration time as Unix seconds (UTC)
nbfNot-before time; reject the token before this instant
iatIssued-at time
jtiJWT ID — a unique identifier for this token

How to read exp and iat

Time claims are NumericDate values: Unix seconds since 1970-01-01T00:00:00Z, not milliseconds and not ISO-8601 strings. In the sample, iat is 1719792000 (1 July 2024 00:00 UTC) and exp is one hour later.

If a date looks decades off, you probably treated seconds as milliseconds (or the reverse). Convert the number with the Unix Timestamp Converter, or read What Is a Unix Timestamp?.

Decoding is not verification

Anyone who has the token can decode the header and payload. Integrity comes from verifying the signature with the issuer’s secret (HMAC) or public key (RSA/ECDSA). A decoder that only Base64URL-decodes JSON cannot tell a real token from one you edited in a text editor.

Never treat a readable payload as proof that the token is valid. For production auth, verification belongs in your API or identity library — not in a browser inspector.

Common mistakes

These are the failures that show up first when a paste “won’t decode.”

  • Leaving the Bearer prefix on the token. Strip scheme labels before splitting.
  • Decoding with standard Base64 instead of Base64URL.
  • Assuming three segments means the signature was checked.
  • Comparing exp to Date.now() without multiplying seconds by 1000 in JavaScript.
  • Pasting a live access token into a third-party website. Prefer a local decoder; Toolshelf does not upload the token.

Inspect a token in the browser

Open the JWT Decoder & Inspector, paste the compact token, and decode it. You will see header JSON, payload JSON, and human-readable iat / exp / nbf times. Use JSON Formatter if you need to pretty-print a claim object you copied out, and Base64 Encoder & Decoder if you are learning Base64URL separately.

Frequently asked questions

How do I decode a JWT payload?
Split the token on dots, Base64URL-decode the second segment, and parse the result as JSON. That payload is readable; it is not signature-verified.
Why does my JWT fail to decode?
Typical causes are a Bearer prefix, extra whitespace or quotes, standard Base64 instead of Base64URL, or a JWE (five segments) whose payload is encrypted.
Can I decode a JWT without the secret?
Yes. The header and payload of a compact JWS are encoded, not encrypted. The secret or private key is required to verify the signature, not to read the JSON.
Is it safe to paste a JWT into an online decoder?
Treat tokens as secrets. Prefer a decoder that runs in your browser and does not upload the token. Still avoid pasting live production tokens into screenshots or tickets.

Try these Toolshelf tools

Related articles

← All articles