JWT Decoder
Paste a JWT to see its header, payload, and standard claims. Everything runs locally in your browser; nothing you paste is sent to Docspira.
Nothing you paste is sent to Docspira. Privacy.
Decoded locally. Signature not verified.
What is a JWT?
A JSON Web Token (JWT) is a compact, URL-safe token made of three Base64URL-encoded parts separated by periods: a header, a payload, and a signature. Decoding reveals the token's header and payload contents; it does not verify its signature or authenticity. A token that decodes successfully can still be forged, expired, or signed with an unexpected key; only a real signature check against the correct key can establish trust. Docspira decodes entirely in your browser and never sends the token anywhere.
What this tool does
Inspect the header and payload of a JSON Web Token.
Anatomy of a JWT
A JWT is three Base64URL-encoded parts joined by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNzkwMzgwODAwfQ.<signature>
└──────────── header ──────────────┘ └───────────────── payload ─────────────────┘ └ signature ┘
| Part | Contains | Readable by anyone? |
|---|---|---|
| Header | The algorithm (alg) and token type (typ), sometimes a key ID (kid) |
Yes |
| Payload | The claims: who the token is about, who issued it, when it expires, plus any custom data | Yes |
| Signature | A cryptographic signature over the first two parts | Only verifiable with the right key |
Base64URL is encoding, not encryption. Anyone who has the token can read the header and payload, which is exactly what this decoder does. Never put passwords, personal documents or secrets in a JWT payload.
Standard claims
| Claim | Name | What it means |
|---|---|---|
iss |
Issuer | Who created and signed the token (for example your auth server URL) |
sub |
Subject | Who the token is about, usually a user ID |
aud |
Audience | Which service the token is meant for. An API should reject tokens meant for another audience |
exp |
Expiration | When the token stops being valid |
nbf |
Not before | When the token starts being valid |
iat |
Issued at | When the token was created |
jti |
JWT ID | A unique ID, used to prevent replay or to revoke a single token |
exp, nbf and iat are Unix timestamps in seconds, not milliseconds. The decoder converts them to readable dates. A common bug is creating them with JavaScript's Date.now(), which returns milliseconds and produces tokens that expire tens of thousands of years from now. Use Math.floor(Date.now() / 1000). To convert other timestamps, use the Unix timestamp converter.
Signing algorithms you'll see in the header
alg |
Type | Verified with |
|---|---|---|
HS256, HS384, HS512 |
HMAC with a shared secret | The same secret that signed it. Anyone who can verify can also create tokens |
RS256, RS384, RS512 |
RSA signature | The issuer's public key, often published at a JWKS URL |
ES256, ES384 |
ECDSA signature | The issuer's public key |
EdDSA |
Ed25519 signature | The issuer's public key |
none |
No signature at all | Nothing. Servers must reject it unless they explicitly expect unsigned tokens |
Seeing alg: none in a token you didn't expect is a red flag: a classic attack is changing the algorithm to none and dropping the signature, hoping the server doesn't check.
Decoding is not verifying
This tool shows what a token says. It does not prove the token is genuine. Anyone can create a token whose payload says "role": "admin". Only a signature check with the correct key, done by your server or your JWT library, establishes that the issuer really signed it. Your server should also check exp, nbf, iss and aud, not just the signature.
Why a token won't decode
| Symptom | Cause |
|---|---|
| "Expected 3 segments, found 5" | It's a JWE (encrypted JWT), not a signed JWT. The payload is encrypted and can't be read without the decryption key |
| "Expected 3 segments, found 1" | You copied a session ID or an opaque access token, not a JWT. Not every token is a JWT |
| Header or payload "invalid Base64URL" | The token was cut off when copying, or contains a line break or extra characters |
| Works in the decoder, rejected by the API | Expired (exp in the past), wrong audience, clock skew between servers, or the signature doesn't match the key the API uses |
You can paste the token with or without the Bearer prefix, or the whole Authorization: Bearer ... header line; the prefix is ignored.
FAQ
Is it safe to paste a production token here?
The token is decoded in your browser and is not sent to Docspira, so it doesn't leave your device. Still, treat a live access token like a password: anyone who has it can use it until it expires, so avoid pasting it into tools that do send data to a server, and never share screenshots of it.
Can I edit the payload and use the modified token?
No. Changing any character in the header or payload invalidates the signature, and a correctly configured server will reject the token.
How do I check if a JWT is expired?
Paste it above: the decoder shows exp as a date and marks the token Expired or Not expired against your computer's clock. Servers often allow a few seconds or minutes of clock skew, so a token that just expired may still be accepted briefly.
What's the difference between a JWT and an OAuth access token?
OAuth defines how tokens are issued, not their format. Many OAuth servers issue access tokens as JWTs, but some issue opaque random strings that only the issuing server can look up.
Why is my JWT so long?
Every claim adds bytes, and Base64URL adds about a third on top. Large tokens sent on every request slow things down and can hit header size limits (often 8 KB). Keep payloads small and store bulky data on the server.
Before you start
Decoding shows what a token contains but does not verify its signature, issuer, expiry, or authorization.
Privacy
This tool runs in your browser; the text or file you choose is not uploaded for processing. Read the privacy details.