JWT decoder

Decode the header and payload of any JSON Web Token — privately, in your browser. Decode only, never verified.

Decode only — not verified. This tool reads a token; it does not check the signature, so it cannot confirm the token is authentic or untampered. Everything runs locally in your browser and nothing is sent anywhere.

What a JSON Web Token actually contains

A JSON Web Token (JWT) is a compact, URL-safe way to carry a set of claims — facts about a user or request — between two parties. You meet them constantly: they are the bearer tokens behind most modern login systems, single sign-on flows and stateless APIs. A signed JWT is three Base64URL strings joined by dots, in the form header.payload.signature. This decoder unpacks the first two, which are plain JSON, so you can read exactly what a token is asserting.

How the decoding works

Each segment is encoded with Base64URL, a URL-safe variant of Base64. To turn a segment back into text the tool runs four steps:

  1. Split the token on the . character into header, payload and signature.
  2. In each of the first two parts, swap - back to + and _ back to /.
  3. Re-add the dropped = padding until the length is a multiple of four, then Base64-decode to raw bytes and read them as UTF-8 text.
  4. Parse that text with JSON.parse and pretty-print it with two-space indentation.

The padding rule is exact: the number of = characters to add is (4 − len mod 4) mod 4. So a segment of length 22 needs (4 − 22 mod 4) mod 4 = (4 − 2) mod 4 = 2 padding characters before decoding.

A worked example

Take the classic test token whose payload segment is eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. After Base64URL decoding it becomes {"sub":"1234567890","name":"Jane Doe","iat":1516239022}. The iat claim is the Unix timestamp 1516239022; multiplied by 1000 it becomes a JavaScript date of Thu, 18 Jan 2018, 01:30:22 UTC. If that token also carried an exp claim in the past, the status line below the table would read “expired”.

Registered time claims

ClaimNameMeaning
iatIssued AtWhen the token was created.
nbfNot BeforeEarliest time the token is valid.
expExpirationTime after which the token must be rejected.

All three are seconds since the Unix epoch (1 January 1970 UTC). A token is currently usable only when nbf ≤ now < exp.

Privacy note: this decoder runs with no server and no analytics on your input. The token you paste is decoded on your device and exists only in this browser tab. Because a JWT is signed rather than encrypted, treat its contents as readable by anyone who holds it — never store secrets inside a payload.

Frequently asked questions

Does this tool verify the JWT signature?

No. This is a decoder only — it splits the token, Base64URL-decodes the header and payload, and shows you the JSON. It does not check the signature against a secret or public key, so it cannot tell you whether a token is authentic or was tampered with. To verify a token you need the issuer’s signing key on a trusted server.

Is it safe to paste a real token here?

Decoding happens entirely in your browser with plain JavaScript. Nothing is uploaded, logged or stored, and the token never leaves your device. That said, treat any live token as a password: it grants access while it is valid, so avoid pasting production tokens into tools you do not trust, and prefer expired or test tokens.

What do the exp, iat and nbf claims mean?

They are registered time claims expressed as Unix timestamps (seconds since 1 January 1970 UTC). “iat” is when the token was issued, “nbf” (not before) is the earliest time it is valid, and “exp” is when it expires. This tool converts each to a readable local date and flags whether the token is currently expired or not yet active.

Why is the payload readable if it is encrypted?

A standard JWT is signed, not encrypted. Base64URL is an encoding, not a cipher — anyone holding the token can read every claim inside it. Never put passwords or sensitive personal data in a JWT payload; the signature only proves the claims were not changed, it does not hide them.

What does “Base64URL” decoding involve?

JWT segments use the URL-safe Base64 alphabet: “-” replaces “+”, “_” replaces “/”, and trailing “=” padding is dropped. To decode we reverse those substitutions, restore the padding so the length is a multiple of four, then run a normal Base64 decode and parse the result as JSON.

Why does my token show three parts separated by dots?

A signed JWT has the shape header.payload.signature. Each part is independently Base64URL-encoded. This tool decodes the first two human-readable parts; the third is the raw signature, which is binary data and only meaningful to code that holds the verification key.