How to use it
- On the Decode tab, paste the JWT — a leading
Beareris fine — and the header and payload are parsed at once. - In the claims table, read
exp,iatandnbfin local time with a verdict beside them: expired N days ago, or valid for another N hours. Amber means under an hour left. - Type the secret and, for HS256, HS384 and HS512, the tool checks the signature through WebCrypto and says whether it matches.
- On the Create tab, pick the algorithm, edit the payload as JSON, set a lifetime with +exp in an hour or +exp in a day, type a secret and press Create token.
- Take the token with Copy; Check throws it back into the decoder.
What the tool does
A JWT (JSON Web Token, RFC 7519) is three dot-separated parts: the header (algorithm and type), the payload (the claims — who, for whom, until when) and the signature. The first two are ordinary JSON in Base64url, so anyone can read them without a key. The decoder splits the token, prints the JSON with highlighting, converts exp, iat and nbf from Unix seconds into dates in your own time zone, and says straight away whether the token is still alive.
The signature is the only thing standing between a token and a forgery. For the symmetric algorithms HS256, HS384 and HS512 it can be checked right here: type the secret and the tool computes the HMAC through WebCrypto and compares it with the third part. RS256, ES256 and the other asymmetric schemes need the public key of the issuing server, so for those this page decodes and stops there.
The standard claims the table spells out
| Claim | Meaning | What the tool shows |
|---|---|---|
iss | Who issued it (issuer) | The value as it is |
sub | Who the token is about (subject), usually a user ID | The value as it is |
aud | Who it is for (audience), the receiving service | A string, or a comma-separated list |
exp | Expires at (Unix time) | Date, time, and expired or valid for another |
iat | Issued at | Date, and issued N minutes ago |
nbf | Not valid before | Date, and already in force or not yet |
jti | Unique token ID | The value as it is |
Where this earns its keep
- Debugging network and tracker APIs: the server answers 401 — decode the token and look at whether
exphas passed and whetheraudis the right one. - Looking at someone else backend: the
nonealgorithm, or a short secret under HS256, are the classic holes, and both are visible in a minute. - Test tokens for Postman and automated tests: the builder makes an HS256 token with the payload and lifetime you want, with no library to install.
- Telegram Mini Apps and OAuth: an id_token from Google, Apple or any other provider is a JWT too, and this is a convenient place to see what is inside.
Security
The token and the secret are handled in your browser only. Nothing reaches the affpapa.org server and the secret is not even written to local storage. Even so, a production secret does not belong in a third-party tool: use the builder for test keys, and verify signatures of real tokens against a test environment.
Questions
Can a JWT be decoded without the secret?
The header and the payload, yes: that is Base64url, not encryption, and any decoder reads them. The secret is needed only to check the signature, that is, to establish the token was not forged. Do not put anything in the payload that the client should not see.
What does expired N days ago mean when the server still accepts the token?
The tool compares the exp claim against the clock of your own computer. If the server accepts an expired token, either it does not check exp — a bug on its side — or its clock is wrong.
Why does the signature come out wrong when the secret is right?
The usual causes: the server stores the secret in Base64 and decodes it before signing, while you pasted it as text; a stray space or newline at the end of the secret; the algorithm in the header is not the one the token was actually signed with.
Why can RS256 and ES256 not be verified here?
An asymmetric signature is verified with the public key of the server, which the tool does not have. The decoder still shows the header and the payload, and the signature line says the check is unavailable in the browser.
Is my secret stored anywhere?
No. It lives in the input field until you reload the page: not in local storage, not sent anywhere. The builder payload is remembered locally for convenience, which is why secrets do not belong in it.