JWT Decoder
Decode JSON Web Tokens and see the header, payload, and timestamp claims as readable dates.
Token
The JWT decoder takes a JSON Web Token and breaks it into its three parts: the header (algorithm metadata), the payload (the actual claims), and a timestamp claims section that converts iat, exp, and nbf from Unix integers into readable dates. Decoding happens entirely in your browser, so the token never leaves your machine.
What a JWT Actually Contains
A JSON Web Token is three Base64-encoded segments joined with dots: header.payload.signature. The header and payload are both JSON objects, while the signature is a cryptographic value that proves the token has not been modified. The decoder unpacks the first two parts and ignores the third (verifying the signature requires a secret or public key that depends on the issuing service).
- Header: contains the signing algorithm (alg) and the token type (typ). Common alg values are HS256 (HMAC SHA-256), RS256 (RSA SHA-256), and ES256 (ECDSA P-256). The header is usually small and rarely inspected unless you suspect an algorithm-confusion attack.
- Payload: the JSON object that carries the actual claims. Standard claims include sub (subject, usually a user ID), iss (issuer), aud (audience), iat (issued at), exp (expiry), and nbf (not before). Custom claims like email, roles, or tenant_id appear here too.
- Signature: not decoded by this tool because verifying it requires the secret or public key. To verify a signature, paste the token into your backend and use the matching library (jsonwebtoken in Node, PyJWT in Python, java-jwt in Java).
Reading the Timestamp Claims
The most common JWT bugs come from misreading the timestamp claims. They are stored as Unix integers (seconds since 1970), and the decoder converts each one into a readable date plus a relative time:
- iat (issued at): the moment the token was generated. Used to track token age and to invalidate tokens issued before a server-side revocation event.
- exp (expires): the moment after which the token must be rejected. A token with exp in the past is expired and should never be accepted.
- nbf (not before): the earliest moment the token is valid. Used for scheduled access (a token that becomes valid at midnight) or for short clock-skew tolerance windows.
The decoder uses your browser's local timezone for display so the times match what you would see in a log file or admin panel. To check the raw Unix timestamp on its own, paste it into the main timestamp converter. For computing how long until a token expires, use the date difference calculator with the exp timestamp and the current time.
When to Decode a JWT
JWT decoding is the first step in almost every authentication debugging session. Typical use cases:
- Auth bug triage: a request is rejected with "token expired" - decode the token to see the exact exp time and compare against the server clock.
- Permission verification: check which roles, scopes, or tenant claims a token carries before passing it to a downstream service.
- Token introspection in CI: dump the decoded payload of a test fixture to confirm it has the expected user ID, audience, or feature flag.
- Integration testing: grab a real token from a browser session and see what your auth provider actually issues vs what its documentation claims.
- Security audits: spot tokens signed with weak algorithms (none, HS256 when RS256 was expected) or with suspicious extra claims.
For decoding other identifier formats that embed timestamps, see the Snowflake decoder (Discord/Twitter IDs), the UUID decoder (versions 1, 6, 7), the ULID decoder, or the MongoDB ObjectId decoder.
What the Decoder Does Not Do
This is a viewer, not a verifier. The decoder will not tell you whether a signature is valid because that requires the secret (for symmetric algorithms like HS256) or the public key (for asymmetric algorithms like RS256). A token with a tampered payload but a syntactically valid structure will still decode here - it just will not pass signature verification on the server. Treat decoded JWT contents as "what the holder claims" until verified.
The decoder also does not store, log, or transmit your token. Decoding runs as JavaScript inside your browser tab, so even sensitive tokens (production credentials, internal service tokens) can be safely inspected without exposing them to a third party. Closing the tab clears everything.
Frequently Asked Questions
No. Decoding runs entirely in your browser using local JavaScript. The token is never sent to a server, logged, or stored anywhere. This makes the decoder safe to use for production credentials and internal service tokens. Closing the browser tab clears the input from memory.
No. Signature verification requires the secret (for symmetric algorithms like HS256) or the public key (for asymmetric algorithms like RS256/ES256). The decoder is a viewer for the unsigned content. Treat the decoded claims as untrusted input until the receiving server validates the signature with the correct key.
iat (issued at) is when the token was created. exp (expires) is the cutoff after which the token must be rejected. nbf (not before) is the earliest moment the token is valid. All three are stored as Unix timestamps in seconds. The decoder converts each one into a readable date so you do not need to convert the integer manually.
The most common cause is clock skew: your local clock or the verifying server's clock is off by more than the allowed tolerance (usually 30 to 60 seconds). Compare the iat and exp values from the decoder against the live clock on the epoch clock page to see whether your local time is in sync. If your machine is correct, the issuing server's clock is the problem.
A JWT has three parts separated by dots: header.payload.signature. The header is a Base64-encoded JSON object naming the algorithm. The payload is a Base64-encoded JSON object containing the claims. The signature is a Base64-encoded cryptographic value computed over the first two parts. The decoder unpacks the header and payload; the signature is opaque without the key.
HS256 (HMAC with SHA-256) uses a shared secret and is common in single-service deployments. RS256 (RSA with SHA-256) and ES256 (ECDSA P-256) use a private key to sign and a public key to verify, which is the standard pattern for OAuth and OpenID Connect providers. Avoid the none algorithm in production: it means the token is not signed at all and any forged token will be accepted.
Yes. JWTs are signed, not encrypted (unless they are JWEs, which is a different format). The header and payload are Base64-encoded plain text that anyone with the token can read. This is by design: the signature protects against tampering, not against reading. If you need confidentiality, use JWE (JSON Web Encryption) or send the token only over TLS.
A session cookie is an opaque random ID that maps to server-side state. A JWT carries the state inside the token itself, signed by the issuer. The server can verify a JWT without a database lookup, which scales better, but it also cannot revoke a JWT before it expires without maintaining a denylist. Pick session cookies for short-lived web sessions, JWTs for stateless APIs and microservices.
The sub (subject) claim is the identifier of the user or entity the token represents. Many auth providers issue opaque random IDs (UUIDs, ULIDs, or proprietary formats) rather than numeric user IDs to avoid leaking information. If the sub looks like a UUID or ULID, paste it into the UUID decoder or ULID decoder to check whether the format embeds a creation timestamp.
Bearer is the HTTP authentication scheme used to carry JWTs and other opaque tokens. The full header looks like Authorization: Bearer eyJhbGciOiJI... and tells the server that the bearer (holder) of the token is authenticated. Strip the leading Bearer plus the space before pasting into the decoder; only the JWT portion is needed.