It's safe if the decoder runs entirely in your browser and the token is expired or from a test system. It's risky if you paste a live production token into a site that sends it to a server. A JWT isn't just data about a login. It often is the login, and whoever holds it can use it until it expires. Our JWT Decoder splits and decodes the token on your device with no network request. Below is how to check any other decoder, what's actually inside a token, and what to do if you've already pasted one somewhere you shouldn't have.
Most JWTs are bearer tokens. The server that issued one doesn't check who's presenting it. It checks the signature and the expiry, and if both pass, the request goes through. So a valid access token copied from your browser's dev tools works just as well from somebody else's laptop.
That's the real risk with online decoders. Decoding itself is harmless, because the payload was never secret. The danger is a copy of a still-valid credential ending up in someone's server logs, analytics or error reports.
No, not in the usual kind. A JWT, defined in RFC 7519, is three base64url-encoded segments joined by dots: header, payload and signature. Base64url is an encoding, not encryption, so anyone with the token can read every claim in it. The signature only proves the token hasn't been changed since the issuer signed it. It doesn't hide anything.
There is an encrypted variant, JSON Web Encryption (RFC 7516), and you can spot it by counting dots. A signed token has three parts. An encrypted one has five, and its payload decodes to gibberish without the key.
The standard claims, listed in RFC 7519 section 4.1, are mostly harmless on their own. The custom claims that apps add are where personal data turns up.
| Claim | Meaning | Sensitive? |
|---|---|---|
| iss | Who issued the token | Low. Reveals your identity provider or domain |
| sub | The user or account ID | Medium. A stable ID that can link activity |
| aud | Which API the token is for | Low |
| exp | Expiry time, in Unix seconds | No, but tells an attacker how long it works |
| nbf / iat | Not-before and issued-at times | No |
| jti | A unique token ID | No |
| email, name, roles, tenant | Custom claims added by the app | Often high. Personal data and permissions |
Don't rely on a "we never store your token" line alone. When we checked in October 2026, jwt.io, the best-known decoder (run by Auth0, part of Okta), didn't state on its home page whether processing happens in the browser. It may well be client-side, but the network tab is how you'd know for sure.
Yes, and for production tokens that's the safest route. With Python installed, this prints the payload:
python3 -c "import base64,json,sys; p=sys.argv[1].split('.')[1]; print(json.loads(base64.urlsafe_b64decode(p+'='*(-len(p)%4))))" YOUR_TOKEN
The '='*(-len(p)%4) part restores the padding that base64url strips off. Plain base64 -d in a terminal usually prints the payload but complains about that missing padding, which is why the Python version is tidier. You can also run any base64url segment through our Base64 Encoder with URL-safe mode on, and tidy the result with the JSON Formatter. Both run locally too.
They're Unix timestamps: seconds since January 1, 1970, UTC. Our decoder converts them to your local time. Here are some reference points if you're reading one by hand:
| Timestamp | Date and time (UTC) |
|---|---|
| 1700000000 | November 14, 2023, 22:13 |
| 1735689600 | January 1, 2025, 00:00 |
| 1767225600 | January 1, 2026, 00:00 |
| 1800000000 | January 15, 2027, 08:00 |
| 2000000000 | May 18, 2033, 03:33 |
| 2147483647 | January 19, 2038, 03:14 (the 32-bit limit) |
Subtract iat from exp to get the token's lifetime in seconds. 3600 is one hour and 86400 is one day. A long-lived access token is a bigger problem if it leaks, which is worth raising with whoever runs the API.
No. Decoding reads the claims, and validating means checking the signature against the issuer's key. Our decoder shows a green "VALID" or red "EXPIRED" badge, but that badge only compares exp to your clock. It doesn't check the signature, and a forged token with a future expiry would show green too. RFC 8725, the JWT best-practices document, warns servers never to trust a token's own alg header without checking it against an allowed list. That rule exists because of exactly this kind of confusion.
Signature checks are where pasting gets riskier. To verify an HS256 token, a tool needs the shared secret, and that secret can mint new tokens for every user. Never paste a production HMAC secret into a website. RS256 and ES256 tokens verify with a public key, which is fine to share.
Hashing is a different job from signing, but if you're comparing secrets or fingerprints, our Hash Generator also runs offline. For more no-upload tools, see the best free privacy tools.
For expired or test tokens, yes. For live production tokens, check first: open developer tools, watch the Network tab and paste a test token to see whether it's sent anywhere. In October 2026 jwt.io's home page didn't say whether decoding happens in the browser, so the network check is the reliable way to know.
Usually, yes, until it expires. Most JWTs are bearer tokens, so the server accepts them from whoever presents them as long as the signature is valid and the exp time hasn't passed.
Not in a normal signed JWT. The header and payload are base64url-encoded, which anyone can decode. Only JSON Web Encryption tokens, which have five dot-separated parts instead of three, hide the payload.
No. Decoding just reads the header and payload. Verification checks the signature with the issuer's secret or public key. A decoder that labels a token valid based only on the exp claim hasn't checked the signature.
Sign out or revoke the session so the refresh token stops working, and note when the access token's exp claim runs out. If a signing secret leaked, rotate it right away so tokens signed with it are rejected.