# JWT Decoder

> Paste a JSON Web Token to read its header and payload, with iat, nbf and exp shown as dates.

- Page: https://decoder.tools/jwt-decoder
- Category: Web, API & Tokens
- Status: live, runs in the browser
- Last reviewed: 2026-10-23

A JWT decoder splits a JSON Web Token at its two dots and Base64URL-decodes the first two parts, so you can read the header (how the token was signed) and the payload (the claims it carries).

## Example

```text Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSBMb3ZlbGFjZSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzAwMDAzNjAwfQ.pBSHJDXCRuBqZrds3AJ_St-OREr2Ma5GW9qHdm8EJik
```

```text Output
HEADER
{
  "alg": "HS256",
  "typ": "JWT"
}

PAYLOAD
{
  "sub": "1234567890",
  "name": "Ada Lovelace",
  "role": "admin",
  "iat": 1700000000,
  "exp": 1700003600
}
```

Alongside the JSON, the decoder shows **Issued: Tue, 14 Nov 2023 22:13:20 GMT** and **Expires: Tue, 14 Nov 2023 23:13:20 GMT**, and marks this token as expired.

## How a JWT is built

A JWT (RFC 7519) has three parts separated by dots: `header.payload.signature`.

1. **Header.** JSON naming the signing algorithm (`alg`) and usually the type (`typ`). It may also include `kid`, the ID of the key used to sign it.
2. **Payload.** JSON with the claims: who the token is about, who issued it, what it allows and when it expires.
3. **Signature.** Computed over the first two parts with a secret or a private key. It proves the token hasn't been changed, but it does not hide anything.

The header and payload are only Base64URL-encoded, not encrypted. Anyone who has the token can read them, which is why a JWT must never contain passwords or other secrets. (Encrypted tokens, JWE, have five parts instead of three and can't be read without the key.)

## Standard claims

| Claim | Name | Meaning |
|---|---|---|
| `iss` | Issuer | Who created and signed the token |
| `sub` | Subject | The user or entity the token is about |
| `aud` | Audience | Who the token is meant for. APIs should reject tokens for another audience |
| `exp` | Expiration | Unix time after which the token is invalid |
| `nbf` | Not before | Unix time before which the token is invalid |
| `iat` | Issued at | Unix time the token was created |
| `jti` | JWT ID | Unique ID, used to prevent replay |

Times are in **seconds** since 1970. To convert one by hand, use the [Unix timestamp converter](/unix-timestamp-converter).

## How to use the JWT decoder

1. Paste the token. A leading `Bearer ` is fine, and so is a token without a signature.
2. Read the decoded header and payload.
3. Check the algorithm and the expiry line. Remember that decoding doesn't verify the signature.

## Decode a JWT in code

```js JavaScript (Node.js)
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSBMb3ZlbGFjZSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzAwMDAzNjAwfQ.pBSHJDXCRuBqZrds3AJ_St-OREr2Ma5GW9qHdm8EJik";
const [header, payload] = token.split(".").slice(0, 2)
  .map((part) => JSON.parse(Buffer.from(part, "base64url").toString("utf8")));
console.log(header.alg, payload.sub, new Date(payload.exp * 1000).toISOString());
```

```python Python
import base64, json

token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFkYSBMb3ZlbGFjZSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcwMDAwMDAwMCwiZXhwIjoxNzAwMDAzNjAwfQ.pBSHJDXCRuBqZrds3AJ_St-OREr2Ma5GW9qHdm8EJik"
payload = token.split(".")[1]
payload += "=" * (-len(payload) % 4)  # restore Base64 padding
print(json.loads(base64.urlsafe_b64decode(payload)))
```

To **verify** a token in production, use a maintained library such as `jose` (JavaScript) or `PyJWT` (Python) and pin the expected algorithm.

## JWT at a glance

| | |
|---|---|
| Specification | RFC 7519 (JWT), RFC 7515 (JWS), RFC 7516 (JWE) |
| Structure | `header.payload.signature`, each part Base64URL |
| Common algorithms | HS256 (shared secret), RS256 and ES256 (public/private key) |
| Time claims | Unix seconds: `iat`, `nbf`, `exp` |
| Encrypted? | No. Signed JWTs are readable by anyone |

## FAQ

### Does decoding a JWT verify it?

No. Decoding only reads the header and payload. Verification checks the signature with the issuer's secret or public key, and also checks `exp`, `aud` and `iss`. A server must always verify before trusting any claim.

### Is it safe to paste a JWT here?

The decoding runs in your browser and the token isn't sent anywhere. Still treat live tokens like passwords: anyone who copies one can use it until it expires. Prefer expired or test tokens when you can.

### What does alg "none" mean?

It means the token is unsigned. Some old libraries accepted such tokens as valid, which let attackers forge any claims. A server should reject `none` and only accept the algorithm it expects.

### Why does my token start with eyJ?

`eyJ` is the Base64 encoding of `{"`, the start of a JSON object. Both the header and the payload begin with it, which makes JWTs easy to spot in logs and headers.

### What is the difference between HS256 and RS256?

HS256 uses one shared secret to sign and verify, so every service that verifies tokens can also create them. RS256 signs with a private key and verifies with a public key, so verifiers can't forge tokens. Use RS256 or ES256 when tokens cross service boundaries.
