Skip to content
Plaintools

JWT decoder

Paste a JWT. We base64url-decode the header and payload in this tab and format iat, exp, and nbf as dates. The signature is shown, not verified. Treat any token you paste as secret — this page does not send it anywhere, but your browser extensions still can.

The token is decoded in this tab. It is not sent anywhere.

JWT decoder example

The jwt.io sample token

The classic HS256 example decodes to alg HS256, sub 1234567890, and an exp in 2018, so the expired flag is true.

JWT decoder how-to

  1. Trim. Split on ".". Require exactly three segments, each length > 0. Otherwise: not a JWT / JWE unsupported.
  2. For header and payload: replace - with +, _ with /; pad with "=" until length % 4 === 0; atob to bytes; TextDecoder UTF-8; JSON.parse. Must be a non-array object.
  3. Leave the third segment as signature. Do not HMAC or check alg.
  4. If iat/exp/nbf is a finite number, format new Date(value * 1000) as `${toISOString()} (${toLocaleString()})`.
  5. expired = typeof exp === "number" ? exp * 1000 < Date.now() : false. notYetValid = typeof nbf === "number" ? nbf * 1000 > Date.now() : false.

Related tools

Dev

Text diff checker

Compare two texts with a live line and word diff. Optional ignore-whitespace.

Dev

Hash generator

Calculate SHA-256, SHA-384, SHA-512, and SHA-1 checksums for text or local files.

Dev

Base64 encode & decode

Encode and decode Base64 strings and files entirely in your browser. Supports full UTF-8 Unicode, URL-safe Base64, line wrapping, and data URLs.

People also use

Dev

Timestamp converter

Convert Unix epoch timestamps in seconds or milliseconds to ISO 8601, UTC, and local time.

Dev

CSV to JSON converter

Convert CSV records to a JSON array of objects with header mapping and type detection.

Dev

Subnet calculator

Calculate IPv4 network address, broadcast, usable range, subnet mask, and host capacity from CIDR.

Dev

CIDR calculator

Calculate IPv4 CIDR blocks, network address, broadcast address, netmask, usable hosts, and wildcard mask.

JWT decoder FAQ

What is a JWT decoder?
A JWT decoder reads the header and payload of a JSON Web Token so you can inspect claims such as subject, issued-at (iat), and expiry (exp). This online decoder Base64URL-decodes the token in your browser, shows those times as dates, and flags an expired exp — no upload, no account, and no signature check.
Is this the same as jwt.io?
Same decode job, smaller page. jwt.io is a full debugger with encode and signature checks. This page only Base64URL-decodes the header and payload in your tab so you can read claims — no account, no upload, and we do not verify the signature. Use your issuer if you need a new signed token.
Do I need a secret to decode a JWT?
No. The header and payload are Base64URL-encoded JSON, not encrypted, so decoding needs no secret. A secret or public key is only for signature verification, which this tool does not do.
Does this verify the signature?
No. Verification needs the secret or public key and a chosen algorithm. This tool only decodes so you can read claims. A decoded token is not a valid token.
Is my token uploaded?
No. Decoding uses atob and JSON.parse in the page. There is no API route and no analytics beacon that includes the textarea. If you need a stronger guarantee, disconnect the network before you paste.
What does the expired flag mean?
If exp is a numeric claim, we compare exp * 1000 to Date.now() in your timezone. Missing exp means we cannot say. nbf in the future is called out separately; it is not the same as expired.
Why did decoding fail?
A JWT has three base64url segments. We fail on missing dots, invalid base64, or non-JSON header/payload. Encrypted JWEs (five segments) are not supported.
How do I decode a JWT without this page?
Trim and split on “.”. Require exactly three nonempty segments (JWEs with five segments are unsupported). For header and payload: base64url (replace - with +, _ with /; pad with “=” to a multiple of 4); atob; UTF-8 JSON object. Show the third segment as the signature; do not verify it. If iat/exp/nbf is a number, display new Date(claim * 1000) as ISO plus locale. expired if exp * 1000 < Date.now(); notYetValid if nbf * 1000 is in the future. Missing exp/nbf is not treated as expired or not-yet-valid.