A compact JWT is just two Base64url-encoded JSON objects — the header and the payload — joined by a third segment called the signature, and you can read either JSON object without a signing secret. The decode step is a mechanical translation: split the token on the dots, Base64url-decode the first segment to recover the header, Base64url-decode the second segment to recover the payload, and leave the third segment untouched unless you actually want to verify the signature. Python developers usually reach for PyJWT or a one-line base64 snippet to do that work, and that path is perfectly fine in a script — but it requires a working interpreter, an installed dependency, and a copy of the token sitting in your terminal or notebook. When you only need to inspect a token quickly — during a debug session on a shared machine, on a Windows host where Python is not set up, or in a restricted environment where installing a package is not an option — a dedicated browser tool gives you the same decoded JSON in two clicks without importing anything. That is exactly what JWT Decoder is for.

how to decode jwt token in python
Decode a JWT in Python and in Your Browser

How to decode a JWT in Python

Most Python developers reach for PyJWT or the standard library. PyJWT's decode() function accepts options={"verify_signature": False} for inspection-only use, and a quick stdlib alternative uses the base64 module to URL-safe-decode the first two segments directly. Neither approach uploads the token, both stay local, and both leave the signature untouched. The friction appears when you do not want to spin up a Python interpreter at all.

Typical PyJWT inspection snippet:

import jwt # pip install PyJWT first token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyfQ.signature" payload = jwt.decode(token, options={"verify_signature": False}) print(payload)

Or with the standard library only:

import base64, json token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaWF0IjoxNTE2MjM5MDIyfQ.signature" def b64url_decode(segment): padding = "=" * (-len(segment) % 4) return base64.urlsafe_b64decode(segment + padding) parts = token.split(".") header = json.loads(b64url_decode(parts[0])) payload = json.loads(b64url_decode(parts[1])) print(header, payload)

Both options work and both leave the signature alone. The expectation is that you only ever run them on tokens you are authorized to inspect, and that you finish by clearing the token from your clipboard and shell history.

Anatomy of a compact JWT token

A compact JWT — the form defined by RFC 7519 that JWT Decoder accepts — always has exactly three segments separated by single dots: a header, a payload, and a signature. Each segment uses the URL-safe Base64 alphabet from RFC 4648, which means uppercase letters, lowercase letters, digits, the hyphen character, and the underscore character — and it omits the trailing equals signs that padding would normally add.

The header usually identifies the signing algorithm and the token type, the payload holds claims such as subject, audience, expiration, issuer, and any application-specific data, and the signature is a digital signature computed over the first two segments with the algorithm declared in the header. Knowing this shape matters because JWT Decoder will refuse anything that does not match — tokens with only one segment, tokens with padding characters, or tokens whose base64 contains characters outside the URL-safe alphabet will produce an error rather than a guess.

How to decode the same token in your browser with JWT Decoder

  1. Copy the compact JWT from wherever it lives — a localStorage value, a server log line, a curl response header, a debug print, or a request inspector — and confirm it really is in the header.payload.signature shape. JWT Decoder will refuse anything that does not split into exactly three dot-separated segments.
  2. Open JWT Decoder in your browser. Because the page runs entirely client-side, no upload happens, no signing key is fetched, and no account is needed; the input is ready the moment the page finishes loading.
  3. Paste the token into the input. The page trims surrounding whitespace, splits on the dots, validates each segment against the URL-safe Base64 alphabet, decodes the first two segments as UTF-8 JSON, and surfaces every standard claim that is present. The third segment is shape-checked only and is never interpreted as a successful signature.
  4. Select Decode JWT. Two clearly labeled blocks appear below the input — header and payload — along with the RFC 7519 registered claims the token contains: issuer, subject, audience, expiration time, not-before time, issued-at time, and JWT ID.
  5. Treat the result as unverified information. A readable payload can be forged, expired, meant for a different audience, or signed with a key you do not trust. Validate the token inside its owning application whenever the question is whether a session is currently valid.

What JWT Decoder surfaces — and what it refuses to do

The tool is deliberately narrow. Knowing the boundary between what you see and what remains unknown is what keeps a quick decode from being mistaken for a security check.

SurfacesRefuses
Header parsed as a UTF-8 JSON objectValidating the JWS signature
Payload parsed as a UTF-8 JSON objectDecrypting a JWE
Registered claims: iss, sub, aud, exp, nbf, iat, jtiFetching a signing key or JWKS document
ISO 8601 timestamp alongside each NumericDate valueChecking the issuer or audience against policy
Algorithm and type fields in the headerApplying clock-skew rules to exp or nbf
Custom private claims from the raw payloadMaking an authorization decision
A clear "unverified" label on every successful decodeAccepting a secret, password, or PEM key

Standard claims at a glance

RFC 7519 defines seven registered claims. JWT Decoder renders each one the same way your Python script would, plus an ISO 8601 reading aid for the three timestamp claims so that a Unix-seconds value is easier to inspect at a glance.

ClaimMeaningWhat the value describes
issIssuerThe principal that minted the token
subSubjectThe principal the token is about
audAudienceThe service or recipient the token is for
expExpirationNumericDate when the token stops being acceptable
nbfNot beforeNumericDate before which the token must be rejected
iatIssued atNumericDate when the token was minted
jtiJWT IDA unique identifier used to prevent replay

The audience claim can be a single string or an array; the tool renders the JSON value without deciding whether it matches your application. NumericDate is a timestamp convention, not a guarantee that the token is currently valid — whether a timestamp is acceptable depends on the issuing system, its configured clock skew, and its validation policy.

Decoding is not verification

A decoded token is a piece of data, not a piece of evidence. Any party that has ever held the token could have re-signed a similar one with a different key, an earlier expiry, an attacker-controlled audience, or no signature at all. JWT Decoder deliberately labels every successful decode as unverified so that a convenient inspection step is not mistaken for a security check — and the right place to make a trust decision is the authentication library of the application that issued the token.

Safe workflow: obtain a token only from an environment where you are authorized to inspect it; paste it into JWT Decoder; review the algorithm field, the standard claims, and any custom claims; then remove the token from the input when you are done. Avoid pasting production credentials into shared screens, issue trackers, chat messages, screenshots, or third-party online decoders — tokens can contain personal identifiers, tenant data, scopes, or other application details even when they are not passwords.

If you actually need to validate a token, use a maintained JWT library inside the service that owns the security decision and verify the algorithm, key, issuer, audience, expiry window, and any application-specific requirements there. JWT Decoder cannot reveal content inside an encrypted JWE, repair a broken token, discover a signing key, or tell you whether a signature is correct.

Pair JWT decoding with nearby tools

A few seconds of follow-up work often reveals more than the token alone:

  • The Unix Timestamp Converter lets you inspect a decoded exp or iat value as a UTC date or in your local time zone, which is useful for "is this token still alive" reasoning during local debugging.
  • The JSON Formatter pretty-prints the raw payload when the structure is nested enough that one-line JSON stops being readable.

Related reading: Generate a JWT Token With a Secret Key Online (HS256).