Decode a JWT as you type — header, payload, signature — and see the encoding underneath. Runs entirely in your browser.
Also searched as jwt decode · jwt token decode · decode jwt · jwt decoder · jwt parser · jwt decoder online · json web token decoder · decode bearer token. It is one tool: a JWT in, its parts out — and back again.
Pick a direction, paste or edit, and the result updates live.
Bearer is ignored.—
—
—
A JWT is three base64url segments joined by dots. The readout below shows the segments, their real byte sizes, and — the part that matters — which characters standard Base64 would have written that base64url had to avoid.
= used| Segment | base64url (as sent) | Bytes | Standard Base64 form | What standard Base64 adds |
|---|
This is the part almost every JWT decoder skips. Standard Base64 uses +, / and = — and all three are meaningful characters in a URL, a query string and a cookie. A JWT is built to travel in exactly those places, so it cannot use standard Base64. It uses the URL-safe variant instead. Here is the same token in both alphabets, live.

———| base64url (what JWT uses) | Standard Base64 | Percent-encoding (URL) | |
|---|---|---|---|
| Alphabet | A–Z a–z 0–9 - _ |
A–Z a–z 0–9 + / |
not an alphabet — an escape layer on top of text |
| Padding | usually omitted | = to a multiple of 4 |
n/a |
| Safe in a query string? | yes, as-is | no — + reads as a space, = collides with key=value |
yes — that is its job |
| Safe in a path segment? | yes | no — / splits the path |
yes |
| Safe in a cookie? | yes | usually — but = and / are fragile |
unnecessary |
| Defined by | RFC 4648 §5 (base64url) | RFC 4648 §4 | RFC 3986 |
+ in a query string is read as a space+ eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIn0.abc+dEfabc dEf — the + became a space+ → -) — which is what JWT does — or %2B if you are stuck with standard Base64/ splits a path segment/api/verify/eyJ0eXAiOiJKV1QifQ.Pj4/PycPj4 and Pyc — not one token/ → _), or %2F= padding gets trimmed or misread== collides with the key=value separator; some stacks strip trailing = outright%2B, %2F, %3D+→-, /→_, and drop =. Same bytes, no escaping, safe in every URL-shaped contextThis is where people over-correct and break their own token. The short answer, for a token that is correctly base64url:
Query string — no. ?token=eyJhbGciOiJIUzI1NiJ9… is already valid: every character in base64url (A–Z a–z 0–9 - _) and the . separators are unreserved in RFC 3986. Nothing needs escaping.
Cookie — no. The cookie-octet set excludes whitespace, ", ,, ; and \. base64url contains none of those, so Set-Cookie: token=eyJ… is fine as-is.
Authorization header — no. Headers are not URLs. Authorization: Bearer eyJ… is sent literally; nothing is percent-decoded on the way in.
You do need percent-encoding when the JWT is not alone in the value. The four real cases:
· You are passing Bearer <token> as a query parameter — the space is not safe. ?auth=Bearer%20eyJ… (or +, but prefer %20). The token itself is still untouched.
· The token sits inside a nested URL — a redirect_uri, a next= parameter, a link in a fragment. The inner URL must be percent-encoded as a whole; the JWT inside it is then carried along untouched.
· You are handed standard Base64, not base64url — legacy systems, a JWS library configured with the standard alphabet, a signature you re-encoded yourself. Then + → %2B, / → %2F, = → %3D are mandatory, not optional.
· You are being defensive — encodeURIComponent(token) is harmless: it leaves every base64url character and the dots unchanged, so a valid JWT passes through byte-for-byte. It costs nothing but length.
%2B → %252B — the receiver decodes once and gets the literal text %2B, not a +%XX text as if it were data — the signature no longer matchesheader.payload.signatureNo login · Unlimited use · No watermark · Runs only in your browser. Decoding and encoding happen locally; the secret you type is never sent anywhere, and no signature is verified unless you do it yourself with the bytes shown above.
Understand the header, payload, and signature; see why Base64URL is not encryption and why signatures must be verified.
Every tool on this site runs entirely in your browser. Pick the encoding problem you have: