How to use
- Paste the token. A leading
Bearercopied from anAuthorizationheader is ignored, as are spaces and line breaks. - Read the Issued / Expires / Not before row: each is shown in UTC with a relative time, and Expires is marked expired or valid against your device clock.
- Read the Header (algorithm and type) and Payload (the claims) as formatted JSON.
- Copy header or Copy payload to paste into a bug report or a test.
What's inside a JWT
A JSON Web Token is three pieces of Base64URL-encoded JSON joined by dots: a header describing how the token is signed, a payload holding the actual claims (user ID, roles, expiry, and whatever else the issuer put in), and a signature. The header and payload are encoded, not encrypted; anyone who has the token can read them, which is exactly why JWTs travel over HTTPS and why sensitive data should not go in the payload. The format is defined in RFC 7519; the Base64URL alphabet it uses is the same one the Base64 tool offers as “URL-safe”.
This is why a JWT debugger is genuinely useful during development: when an API call fails with a 401, decoding the token you sent instantly answers the two most common questions: did it expire, and does the payload actually contain the claim the server is checking for?
Example
The token behind the Load sample button:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSBMb3ZlbGFjZSIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoyMDAwMDAwMDAwfQ.
dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8Udecodes to this header and payload:
{
"alg": "HS256",
"typ": "JWT"
}{
"sub": "1234567890",
"name": "Ada Lovelace",
"iat": 1700000000,
"exp": 2000000000
}The exp claim, 2000000000, is shown as 2033-05-18 03:33:20 UTC and marked valid, because that is later than now. The signature segment is displayed but not checked.
Reading the result
- Header: typically just
alg(the signing algorithm, such as HS256 or RS256) andtyp(“JWT”). Some issuers addkid, the ID of the key they signed with. - Payload. The claims. Some are standard (
sub,iss,aud,exp,iat,nbf,jti); most APIs add their own on top. Shown as-is, formatted with two-space indent. - Issued / Expires / Not before: computed from
iat,expandnbfagainst your device's current time, in UTC, with a relative time (“in 2 hours”, “3 days ago”). Expires is coloured red once the token has expired; Not before only appears when the claim is present. - Header claims / Payload claims tables list every field in the header and payload, one row each, with a plain-English label for the seven RFC 7519 registered claim names (
iss“Issuer”,sub“Subject”, and so on); a field your API added on its own keeps its own key as the label, since this tool has no way to know what it means. - Load sample inserts the token above; Clear empties the box; Copy header and Copy payload copy the formatted JSON.
Edge cases and common errors
- The signature is never checked. Tokens with
"alg": "none", an empty third segment, or a signature made of random letters all decode normally. This tool tells you what a token says, not whether to trust it. - Wrong number of segments.
aaa.bbbis reported as “A JWT has three dot-separated parts; this input has 2”. Five segments (“A JWT has three dot-separated parts; this input has 5”) usually means a JWE, an encrypted token, which cannot be read without the key. expin milliseconds. RFC 7519 defines the timing claims in seconds. A 13-digit value from a library that used milliseconds is read as seconds and shows a date tens of thousands of years away. Paste the raw number into the Unix Timestamp Converter with Auto-detect to see which unit it actually is. Anexpwritten as a string is ignored, and no expiry is shown.- No
expclaim: Expires shows “—” and no valid/expired verdict, because the token has no expiry. - Segments that are not JSON objects. A header that decodes but is not JSON gives “The header decodes, but is not valid JSON”; a payload that is a JSON array rather than an object gives “The payload must be a JSON object”.
- Your clock decides “expired”. A device clock that is a few minutes off will mis-report a token that is about to expire or has just been issued. Check the absolute UTC time shown next to it.
- Copied with extra text: a leading
Beareris stripped and whitespace inside the token is ignored, but surrounding quotes or a trailing comma from a JSON body are not; remove those first.
Verifying a token instead of just reading it
If you need to confirm a token is authentic (not just well-formed), that check has to happen wherever the signing key lives, typically your backend:
Node.js
const jwt = require("jsonwebtoken");
const payload = jwt.verify(token, secretOrPublicKey); // throws if the signature does not matchPython
import jwt # pip install pyjwt
payload = jwt.decode(token, secret_or_public_key, algorithms=["HS256"])Both libraries also check exp and nbf for you. Decoding alone, as this page does, cannot tell you any of that.