JWT Decoder
Decode and inspect any JWT token instantly. See the header, payload and signature in colour. Check expiry with a live countdown. Get plain-English explanations of every standard claim. 100% client-side — your token never leaves your browser.
JWT Decoder Tool
Rate this tool
The JWT decoder that explains what you're looking at
Most JWT decoders show the raw JSON and nothing else. This tool adds expiry status with a time-until-expiry countdown, plain-English explanations of every standard claim, and algorithm-specific security notes — features absent on jwt.io and every other free tool.
exp claim, the tool shows whether the token is VALID, EXPIRED or NOT YET VALID with colour-coded status badges. For valid tokens, the exact time remaining is shown — "expires in 2h 14m 33s". This feature is absent on jwt.io and every other free JWT decoder.iss (issuer), sub (subject), aud (audience), exp (expiration), iat (issued at), nbf (not before) and jti (JWT ID) claims are each shown with their value, a description, and human-readable timestamps for Unix epoch values.alg: none is highlighted with a prominent warning.How to decode a JWT token
exp claim, the status banner shows whether the token is currently VALID, EXPIRED or NOT YET VALID. Valid tokens show a countdown: "expires in 2h 14m". Expired tokens show how long ago they expired. This is the fastest way to diagnose token expiry issues in development and staging environments.alg) is highlighted with a colour-coded security badge: green for asymmetric algorithms like RS256 and ES256, amber for symmetric HS256, and red for the dangerous none algorithm. The typ field confirms this is a JWT.exp, iat and nbf are converted to human-readable dates and times automatically.How this JWT decoder compares
| Feature | LazyTools ✦ | jwt.io | token.dev | jwtdebugger.com |
|---|---|---|---|---|
| Decode header, payload, signature | ✔ Yes | ✔ Yes | ✔ Yes | ✔ Yes |
| Expiry status indicator | ✔ Yes | ✔ Yes | ✔ Some | ✘ No |
| Time-until-expiry countdown | ✔ Live countdown | ✘ No | ✘ No | ✘ No |
| Standard claim explanations | ✔ All 7 claims | ✘ No | ✘ No | ✘ No |
| Algorithm security notes | ✔ With warnings | ✘ No | ✘ No | ✘ No |
| Colour-coded token anatomy | ✔ Yes | ✔ Yes | ✔ Yes | ✔ Yes |
| Copy each section button | ✔ Yes | ✔ Yes | ✘ No | ✘ No |
| Human-readable Unix timestamps | ✔ Yes | ✘ No | ✔ Yes | ✘ No |
| 100% client-side (no token transmitted) | ✔ Confirmed | ✔ Yes | ✔ Yes | Unclear |
| No signup or account required | ✔ Yes | ✔ Yes | ✔ Yes | ✔ Yes |
Standard JWT registered claims — complete reference
| Claim | Full name | Type | Description |
|---|---|---|---|
| iss | Issuer | String / URI | Identifies the principal that issued the JWT. Typically the authentication server URL or service name. |
| sub | Subject | String | Identifies the subject of the JWT — usually the user ID. Must be unique within the issuer's context or globally unique. |
| aud | Audience | String / Array | Identifies the recipients that the JWT is intended for. The server must verify that it is in the audience list or reject the token. |
| exp | Expiration Time | NumericDate | Unix timestamp (seconds since epoch) after which the token must not be accepted. Servers should reject tokens where exp is in the past. |
| nbf | Not Before | NumericDate | Unix timestamp before which the token must not be accepted. Tokens may be issued ahead of time and become valid at nbf. |
| iat | Issued At | NumericDate | Unix timestamp when the JWT was created. Used to determine the age of the token. Does not affect validity unless exp or nbf is set. |
| jti | JWT ID | String | A unique identifier for this token. Used to prevent replay attacks by allowing servers to maintain a list of processed JWT IDs. |
JWT Tokens Explained — Structure, Claims, Algorithms and Security
JSON Web Tokens (JWTs) are the dominant mechanism for stateless authentication and authorisation in modern web applications and APIs. Pronounced "jot", a JWT is a compact, self-contained string that encodes a set of claims — pieces of verifiable information — in a format that can be cryptographically signed and optionally encrypted. When a user logs in, the server creates a JWT, signs it with a secret or private key, and returns it to the client. The client then includes this token in subsequent requests, typically in the Authorization: Bearer <token> header, allowing the server to verify the user's identity and permissions without querying a database on every request.
The three-part JWT structure
Every JWT consists of three Base64URL-encoded parts separated by dots: header.payload.signature. Starting with the header — a JSON object containing the token type (typ: "JWT") and the signing algorithm (alg: "HS256"). Next comes the payload — a JSON object containing the claims: both the registered standard claims (iss, sub, aud, exp, iat, nbf, jti) and any custom claims the application adds. Finally, the signature is computed from the encoded header and payload using the algorithm and key specified in the header, used to verify that neither part has been tampered with. Crucially, the header and payload are only encoded, not encrypted — anyone who has the token can decode and read these sections without any key. The signature protects integrity (tampering is detectable) but not confidentiality (the payload contents are readable). If confidentiality is required, a JWE (JSON Web Encryption) token must be used instead.
Base64URL encoding — why JWT is not encrypted by default
Base64URL is a URL-safe variant of Base64 encoding that replaces + with - and / with _, and omits padding = characters. It is used for the JWT header and payload specifically because JWT tokens are often included in HTTP headers and URL parameters, where standard Base64 characters would cause problems. Because Base64URL is purely an encoding scheme (not encryption), decoding is trivial — no key is required. This is why this tool, and any JWT debugger including jwt.io, can show you the full contents of any JWT without needing the signing key. The security model of JWT relies entirely on the signature: a server that receives a JWT must verify the signature before trusting any claim in the payload.
Signing algorithms — HS256, RS256, ES256 and the danger of "none"
JWT supports multiple signing algorithms, each with different security properties. HS256 (HMAC with SHA-256) is a symmetric algorithm — the same secret key signs and verifies the token. Any service that needs to verify tokens must hold the secret key, which means it could also create tokens, a risk in multi-service architectures. RS256 (RSA with SHA-256) and ES256 (ECDSA with SHA-256) are asymmetric — a private key signs the token and a separate public key verifies it. Verification services can be given the public key without the ability to create new tokens, which is more secure for distributed systems. The algorithm value none means the token is unsigned — a critical vulnerability if the server accepts it, because any attacker can craft a token with arbitrary claims. Modern JWT libraries reject alg: none by default, but older or misconfigured implementations may not.
Token expiry — the exp, nbf and iat claims
Three time-related standard claims control the token's validity window. exp (expiration time) is a Unix timestamp in seconds — if the current time is past this value, the token is invalid and must be rejected. nbf (not before) sets a time before which the token is not valid — useful for tokens issued in advance of when they should be accepted. iat (issued at) records when the token was created, but does not by itself affect validity. Common JWT expiry patterns include short-lived access tokens (15 minutes to 1 hour) paired with longer-lived refresh tokens, token rotation on every refresh, and sliding expiry windows. Debugging token expiry issues — the most common JWT-related bug in development — is the primary use case for tools like this decoder, which shows exact expiry times and time-until-expiry countdowns.
JWT security best practices
Several security best practices apply to JWT implementation. Always validate the signature before trusting any claim — never skip verification in server-side code. Use asymmetric algorithms (RS256 or ES256) rather than HS256 in any system where multiple services consume tokens. Set short expiry times and implement token refresh rather than issuing long-lived tokens. Include an aud (audience) claim and verify it on the receiving service to prevent token misuse across services. Use the jti claim and a denylist if you need to support token revocation before expiry. Store tokens in HttpOnly cookies rather than localStorage to protect against XSS attacks. Never put sensitive data — passwords, full credit card numbers, personal health information — in a JWT payload, since the payload is readable by anyone who has the token.
JWTs versus session cookies — when to use each
JWTs and session cookies are alternative approaches to stateful versus stateless authentication. Session cookies store a session ID that the server looks up in a session store (database or cache) on every request — this allows instant revocation but requires server-side storage and a database lookup per request. JWTs are self-contained — the server does not need to store them or look them up, making them stateless and horizontally scalable. The tradeoff is that JWT revocation before expiry is difficult — you either need a token denylist (which reintroduces server-side state) or you accept that stolen tokens are valid until they expire. JWTs work well for stateless APIs consumed by multiple clients (mobile apps, browser SPAs, third-party services). Session cookies work well for traditional web applications where the server controls the client and revocation is important.
JWT in practice — common debugging scenarios
Several recurring issues appear when working with JWTs in development and production environments. 401 Unauthorized with a valid-looking token: the most common cause is token expiry — check the exp claim against the current time. If the token is not expired, check the aud claim — the receiving service may be rejecting the token because it is not listed as a valid audience. Token works in development but not in production: often caused by clock skew between the token-issuing server and the validating server. JWT libraries typically allow a small leeway (60 seconds) for this, but larger differences require NTP synchronisation. Signature verification failing: confirm that the same algorithm is being used for signing and verification, that the key has not rotated since the token was issued, and that the token has not been accidentally URL-decoded or re-encoded during transmission. Unexpectedly large tokens: JWTs grow with every additional claim in the payload. Keep payload claims minimal — store only what the receiving service needs to make authorisation decisions, and retrieve additional user data from a database or cache using the sub claim as a key.