You need a JWT decoder online because an API just handed you a wall of base64 and a 401, and you want to know what's inside the token before you lose an hour to guessing. Fair. Two things first: decoding a JWT takes one second, and pasting a live token into a random website that uploads it to a server is how access tokens leak. Our JWT decoder decodes entirely in your browser — the token never leaves your machine. That's not a feature, it's the minimum bar for this category of tool.
A JSON Web Token is three base64url-encoded segments joined by dots: header.payload.signature. The header says what algorithm signed it (HS256, RS256, and friends). The payload carries the claims — who you are, who issued the token, when it expires. The signature is the cryptographic proof that the first two parts weren't tampered with. Here's the part that surprises people: the first two segments are just encoded, not encrypted. Anyone holding the token can read everything in it. Which leads directly to rule one of JWTs: never put secrets in the payload. It's a postcard, not a sealed envelope.
A decoder shows you what a token claims. Only signature verification — done server-side, with the secret or public key — tells you whether those claims are true. Any tool (ours included) can decode a token it can't verify, because decoding is just base64. The practical consequence: a decoder is a debugging instrument, not an authentication decision. If your code trusts a token because it decoded cleanly, you've built a door that opens for anyone who can type. Verify signatures on the server, always, with a maintained library — and reject tokens whose header says "alg": "none", a classic attack that politely asks your server to skip verification entirely. Good libraries reject it by default; old tutorials don't mention it.
Inside the payload, the registered claims do the heavy lifting: iss (who issued it), sub (who it's about), aud (who it's for), iat (issued at), and the one you're usually hunting — exp, the expiry. Expiry timestamps are Unix epoch seconds, so "exp": 1789276800 means nothing to a human until you convert it. The decoder surfaces the claims instantly; for the timestamps, our Unix timestamp converter turns them into a date you can argue with. Nine times out of ten, the "mystery 401" is just an expired exp — the token was fine, the clock moved.
Grab the token from your Authorization header (the part after Bearer ). Paste it into the JWT decoder online. Check four things in order: is exp in the past? Does aud match the API you're calling? Does iss match the issuer the server expects? Is the algorithm what the server requires? Those four checks resolve the overwhelming majority of token failures without touching server logs. If the token won't decode at all, it's usually truncation — a copy-paste that dropped characters — or it's not a JWT at all; opaque session tokens and API keys are just strings, and no decoder will find structure that isn't there. For inspecting the raw segments yourself, the base64 encoder/decoder is in the same free toolbox.
Short expiries with refresh tokens beat long-lived access tokens. HttpOnly cookies beat localStorage if XSS is in your threat model (it is). Debug with expired or test-environment tokens when you can — a decoder works the same on a dead token, and a dead token can't hurt you. And keep signing secrets out of client code entirely; if you need to check integrity hashes of anything else during debugging, the hash generator runs client-side too.
Is it safe to paste a JWT into an online decoder? Only if the decoder runs client-side, like ours does — the token stays in your browser. If a tool sends tokens to a server for "processing," a live token can be replayed by whoever operates or breaches that server. When in doubt, debug with an expired token; it decodes identically and can't be abused.
Why does my token decode fine but still get rejected? Decoding proves structure, not validity. The usual culprits, in order: the exp claim is in the past, the aud or iss doesn't match what the server expects, or the signature fails verification because the wrong key or algorithm is in play.
Can I edit a JWT's payload? You can edit the bytes, but the signature immediately stops matching, and any server that verifies will reject it. That's the entire design — payloads are readable by everyone and modifiable by no one without the signing key.
A JWT is readable by design — decode it in your browser, in one paste, without shipping it to someone's server. Trust the decode for debugging; trust only server-side verification for security. Expired exp claims explain most 401s, alg: none should terrify you, and the payload is a postcard. Debug accordingly.
Decode locally, always. The free JWT decoder never sends your token anywhere — same local-first principle as QADIR OS, the sovereign agentic operating system we're building. Join early access — no card required.