DevLab
Encoding⭐ Popularintermediate

JWT Decoder

decode JWT tokens and inspect header, payload, and claims

By Bikram NathLast updated

Paste a JWT and it splits the token at the two dots, base64url-decodes each segment, and renders the header, payload, and signature as formatted JSON. Useful when you have a token like `eyJhbGciOiJSUzI1NiJ9...` from an Authorization header and need to confirm the `exp` claim without spinning up a debugger or curl. Unlike jwt.io, nothing leaves your browser tab.

Try it now — free, instant, no signup

What is JWT Decoder?

A JWT is three base64url-encoded segments joined by dots. This tool splits on those dots, runs each segment through a base64url decoder (padding-aware, replacing `-` with `+` and `_` with `/`), then JSON-parses the result and pretty-prints it so you can read fields like `iss`, `sub`, `aud`, and `exp` at a glance. Example: drop in a token and immediately see that `exp` is `1716076800`, which you can mentally compare to a Unix timestamp or read as the rendered UTC date the tool shows.

When you already have Postman open, its built-in JWT decoder under the Authorization tab is faster for tokens attached to a request. If you only need to inspect the payload and you have Node.js available, `JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString())` in a REPL takes three seconds. This tool earns its place when you are on a machine without Node, inside a browser-only environment, or when you want a clean visual split of header versus payload without writing a one-liner.

One gotcha that catches developers regularly: the `exp` and `iat` claims are Unix timestamps in seconds, not milliseconds. JavaScript's `Date` constructor expects milliseconds, so if you copy the raw `exp` value and pass it to `new Date(exp)` you will get a date in 1970. Multiply by 1000 first. Also, decoding a JWT here tells you what the token claims, not whether the signature is valid — verifying the HMAC or RSA signature requires the secret or public key, which this client-side tool intentionally does not handle.

When to use JWT Decoder

Confirm an `exp` timestamp is in the future before blaming an upstream service for a 401 during local integration testing.
Identify which `alg` value a third-party identity provider is sending when your library throws an unsupported algorithm error.
Extract the `sub` or custom claim from a token copied out of browser DevTools without setting up a local script.

Frequently Asked Questions

Why does the decoded payload show correct JSON but the signature segment looks like random bytes?
The signature segment is intentional binary output from an HMAC or RSA operation, then base64url-encoded. Decoding it back to bytes gives you the raw cryptographic signature, not readable text. This tool renders those bytes as a hex or binary string depending on implementation, but there is nothing to read there — the signature's purpose is machine verification, not human inspection. If you want to verify it, you need the signing secret (HMAC-SHA256) or the issuer's public key (RS256/ES256), neither of which belongs in a browser tool.
My token has a period inside the payload after decoding. Did it get corrupted?
No. JWTs are split on exactly two dots that separate header, payload, and signature. Dots that appear inside any of those three segments after base64url-decoding are part of the JSON content, not structural delimiters. The decoder splits on the first and second dot only, so nested dots in claim values like an email address in a `sub` field (`user@example.com` does not contain dots, but `client_id` values sometimes do) come through intact in the JSON output.
What is the difference between base64 and base64url, and does it matter here?
Standard base64 uses `+` and `/` as the 62nd and 63rd characters and pads with `=`. base64url substitutes `-` for `+` and `_` for `/`, and typically omits padding. JWTs always use base64url. If you copy a JWT segment and try to decode it with `atob()` directly in the browser console, it may fail or return garbage because `atob()` expects standard base64. This tool handles the character substitution and padding restoration before decoding, which is why you should use it rather than a generic base64 decoder for JWT segments.
Can this tool decode a JWT signed with RS256 or ES256, or only HS256?
Decoding works regardless of the algorithm listed in the header's `alg` field. The algorithm only affects how the signature was produced and how it must be verified — it does not affect whether the header and payload segments can be base64url-decoded. You will see `"alg": "RS256"` or `"alg": "ES256"` in the header JSON, and the payload claims will decode normally. Verification of RS256 or ES256 signatures requires the issuer's public key and is out of scope for a client-side decoder.
The `exp` claim decoded fine but the date shown looks wrong by several hours. Why?
The `exp` value is a UTC Unix timestamp. If the rendered date appears offset by your local timezone, the display layer is converting UTC to local time, which is correct behavior — `1716076800` in UTC is a different wall-clock time in IST versus PST. Confusion usually comes from expecting the token to encode a local time. JWT spec (RFC 7519) requires all NumericDate values to represent seconds since the Unix epoch in UTC, so any offset you see is a display formatting choice, not a decoding error.

Related Tools