Skip to content
YAS.SH
Security🔒 Browser (client-side)API available📴 Works offlineintermediate

JWT Decoder

Decodes the header and payload of a JWT without verifying the signature.

Data stays in your browser
Ready to runInstant execution
All tools →
Result

What does this tool do?

Decodes the header and payload of a JWT without verifying the signature.

Why would I use it?

  • You want to inspect the claims inside a token (iss, exp, sub).
  • You are debugging why a token is rejected.
  • You want to see the decoded payload for documentation.

Real-life example

Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIiwibmFtZSI6IkFkYSJ9.sig
Output
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"1","name":"Ada"}

Only the two Base64 sections are decoded.

Input → Process → Output → Next

Input
Paste the full JWT (three dot-separated parts).
Process
The browser decodes the header and payload with URL-safe Base64.
Output
Pretty-printed JSON of header and payload.
Next action
Check exp (expiry) and iss/aud claims against your expectations.

Common mistakes

  • Thinking decoding proves authenticity — anyone can decode a JWT.
  • Ignoring the signature — decode ≠ valid.
  • Trusting claims without verifying the issuer.

What the result means

The output shows what the token claims; verification requires the issuer's key.

Privacy & security

Your input is processed entirely in your browser and never sent to a YAS server.

API

Endpoint
POST https://yas.sh/api/v1/tools/jwt-decoder
Request Header
Content-Type: application/json
cURL
curl -X POST "https://yas.sh/api/v1/tools/jwt-decoder" \
  -H "Content-Type: application/json" \
  -d '{"input":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.sig"}'
JavaScript
const res = await fetch("https://yas.sh/api/v1/tools/jwt-decoder", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
  "input": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.sig"
}),
});
const data = await res.json();
Python
import requests

r = requests.post("https://yas.sh/api/v1/tools/jwt-decoder", json={"input":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.sig"})
data = r.json()
FieldTypeRequiredDescription
inputstringYesThe 3-segment token
Success response
{ "slug": "jwt-decoder", "result": { "header": {...}, "payload": {...} }, "warning": "Decoded WITHOUT signature verification" }

Decode a JWT header & payload (NO signature verification — explicitly flagged).

Error responses
  • 400 VALIDATION_ERROR — invalid input or unsupported option.
  • 413 PAYLOAD_TOO_LARGE — input exceeds the 64 KB limit.
  • 429 RATE_LIMIT_EXCEEDED — rate limit exceeded (60 req/min).
Limits
  • Maximum input: 64 KB per request.
  • Rate limit: 60 requests/min per IP address.
  • Authenticated accounts benefit from higher tier quotas.

JWT Decoder: technical reference, use cases and FAQ

How JWT Decoder works

A JSON Web Token in compact serialization is three Base64URL segments joined by dots: header.payload.signature. Decoding splits on the dots and Base64URL-decodes the first two segments into JSON. The header names the algorithm (alg) and optionally the key (kid); the payload carries the claims. Both are plain text to anyone holding the token — a JWT is signed, not encrypted.

The signature covers the ASCII bytes of header.payload exactly as they appear, which is why you cannot edit a claim and re-join the segments — every change invalidates the signature under the signing key. Verification requires that key, so a browser-side decoder deliberately stops at decoding and does not claim to verify.

Registered claims from RFC 7519 have defined meanings: exp (expiry), nbf (not before) and iat (issued at) are NumericDate values — seconds since the Unix epoch, not milliseconds. iss, aud and sub identify issuer, audience and subject. A validating server must check exp, nbf, iss and aud; skipping the audience check is a common vulnerability that lets a token minted for one service be replayed against another.

When to use it: real-world scenarios

Diagnosing a 401 from an API you do not control

Decode the token and read exp against the current epoch seconds. An expired token, a clock skew of a few minutes, or an aud that does not match the API you are calling explains the majority of unexpected 401 responses.

Confirming which claims your identity provider actually issues

Provider documentation and provider behaviour drift. Decoding a real token shows the exact claim names, whether roles arrive as an array or a space-delimited string, and whether the email claim is present at all.

Reviewing token contents during a security review

Decoding reveals over-sharing: personal data, internal IDs and permission lists that are readable by anyone who obtains the token. Anything sensitive in a payload should move server-side behind an opaque reference token.

Debugging a signature mismatch

Read alg and kid from the header. A kid that no longer appears in the issuer's JWKS means the key was rotated; alg: none or an unexpected HS256 where RS256 was expected is an active attack signature and must be rejected.

Pro tips

  • exp and iat are in seconds. Comparing them against Date.now(), which is milliseconds, produces tokens that appear valid for 50,000 years — use the Unix Timestamp tool to convert.
  • Never accept the alg value from the token itself when verifying. Pin the expected algorithm server-side; algorithm confusion between RS256 and HS256 is a classic JWT vulnerability.
  • Treat every token you paste anywhere as compromised, including here. Decode tokens from staging, or revoke the session afterwards.
  • Long-lived access tokens cannot be revoked without extra infrastructure. Keep access tokens to minutes and put revocation on the refresh token.

Limitations and edge cases

What this tool deliberately does not do, and where it will disagree with other implementations.

  • This tool decodes; it does not verify signatures, because verification requires the signing key and, for RS256/ES256, a JWKS fetch. A decoded token is not a trusted token.
  • Encrypted tokens (JWE, five segments) are not supported — there is nothing to read without the decryption key.
  • Malformed tokens with missing or non-Base64URL segments fail to decode; padding is added automatically where a segment length requires it.
  • Claim semantics are not validated. The tool shows exp as a date but does not decide whether a token is acceptable for your API.

Frequently asked questions

Is it safe to paste a JWT into an online decoder?
Only if the token is expired, from a test environment, or you revoke it afterwards. This decoder runs entirely in your browser and transmits nothing, but a live bearer token is a credential and should be treated as one.
Why can anyone read my JWT payload?
Because JWS tokens are signed, not encrypted — Base64URL is an encoding with no key. Put nothing in the payload you would not put in a URL; use JWE or an opaque token if confidentiality is required.
What does 'alg: none' mean?
It declares an unsecured token with no signature. Any verifier that honours it can be trivially forged, so libraries reject it by default and you should never enable it.
How do I check whether a token has expired?
Compare the exp claim, in seconds since the Unix epoch, against the current time in seconds. Allow a small leeway — typically 30 to 60 seconds — for clock skew between issuer and verifier.
Ask YAS AI
🍪 Cookies & privacy. Essential cookies keep you signed in and remember language and theme. Google AdSense and reCAPTCHA are Google technologies: AdSense runs only after Accept All; reCAPTCHA loads on sign-in and contact forms. See how Google uses data: https://policies.google.com/technologies/partner-sites cookie policy · privacy policy.
Settings