JWT Decoder

Decode and inspect JSON Web Tokens. View header, payload, and signature. Highlights expiry and date claims.

JWT Token

Splits a JWT into its three dot-separated parts and decodes the header and payload from base64url to JSON, starting as soon as the pasted text contains exactly two dots. The exp, iat, and nbf claims are annotated with their UTC times, and exp gets a live valid/expired badge computed against your machine's clock.

Decoding is not verifying

The header and payload of a JWT are base64url-encoded, not encrypted — anyone who holds a token can read every claim in it, and editing the payload is equally trivial. The only thing standing between a token and tampering is the third part, the signature. This page shows the signature as its raw base64url string and deliberately does not verify it: checking an HS256 signature requires the server's signing secret, and a browser page is the wrong place to paste one. Read the decoded payload as claims someone asserts, proven only after the signature is verified server-side.

Seconds, not milliseconds

The registered time claims (exp, iat, nbf) are NumericDate values — seconds since the Unix epoch. A recurring production bug is writing Date.now() — milliseconds — into exp, which pushes the annotated expiry tens of thousands of years into the future; if the date here looks absurd, that is almost certainly what happened. Clock skew cuts the other way: the expired badge compares exp against your local clock, so a token a server still accepts can read as expired here (or vice versa) — most servers tolerate a small skew window.

A complete HS256 token, signed with the secret clipvault-demo
Input: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMDI0IiwibmFtZSI6IkFkYSBMb3ZlbGFjZSIsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjQyNjIyfQ.4SfAyT56WpjFHk8MEleQR_fjmlcYp8Kcj68LdhhoVBY
Output: header: {"alg":"HS256","typ":"JWT"} payload: {"sub":"1024","name":"Ada Lovelace","iat":1516239022,"exp":1516242622}
iat decodes to Thu, 18 Jan 2018 01:30:22 GMT and exp to 02:30:22 GMT — a one-hour token, long expired, so the decoder shows the red Token expired badge. Because the secret is published here, any JWT library can reproduce the signature.

Questions people ask

Is it safe to paste a real production token?

Decoding happens locally — this page makes no network request with your token. The caution is about habit, not this page: a live JWT is a bearer credential, and anyone who obtains it can call your API as you until it expires. Prefer expired or test tokens in shared contexts like screen shares or bug reports.

Why do I get 'expected 3 dot-separated parts'?

Usually the paste includes the 'Bearer ' prefix from an Authorization header, or the token was truncated mid-copy. Encrypted JWTs (JWE) have five dot-separated parts and will also fail — this tool decodes the common three-part signed (JWS) format.

The header and payload decode fine, so why is the signature gibberish?

Because it is not JSON — it is the raw bytes of an HMAC or RSA signature, base64url-encoded. There is nothing to decode into text, which is why this page displays it as-is with a note that it cannot be verified client-side.

An HS256 signature is HMAC-SHA256 over header.payload — the HMAC tool here demonstrates that primitive in isolation, and the timestamp converter handles epoch values you meet outside a token.

Further reading