JWT Decoder & Encoder Online

Decode and parse JWT tokens to inspect their contents, or build and sign your own JWT instantly. Everything runs locally in your browser.

Decode JWT
Encode JWT
馃敀 Your token never leaves your browser. Everything is decoded locally.

Invalid JWT token. Please check the format.

馃敀 Your secret key never leaves your browser. Signing happens locally using the Web Crypto API.

Only HMAC algorithms can be signed client-side. RS256 / ES256 need a private key, sign those on your server.

Used only in your browser to compute the signature.

Invalid JSON in header or payload.

Enter a header, payload and secret to generate a token.

What is a JWT Token?

JWT stands for JSON Web Token. It is an open standard (RFC 7519) for securely transmitting information between two parties as a compact, self-contained JSON object. JWTs are the most widely used format for authentication tokens in modern web applications and APIs.

When you log in to a web app, the server typically generates a JWT and sends it to your browser. Your browser then includes that token on every subsequent API request. The server reads the token, verifies its signature, and knows who you are, without needing to look up a session in a database.

JWT Token Structure

A JWT consists of three Base64URL-encoded parts separated by dots:

header.payload.signature

Each part is independently Base64URL encoded. The encoding is not encryption. The content can be read by anyone who has the token. Only the signature part verifies authenticity.

The Header

The header is a JSON object that describes the token type and the signing algorithm used. It is always Base64URL encoded.

{
"alg": "HS256",
"typ": "JWT"
}

Common algorithm values: HS256 (HMAC + SHA-256, symmetric key), RS256 (RSA + SHA-256, asymmetric), ES256 (ECDSA, asymmetric). The algorithm determines how the signature is created and verified.

The Payload (Claims)

The payload contains claims: statements about the user and any additional metadata. There are three types of claims:

  • Registered claims: Standardized fields defined in the JWT spec. Not required but recommended.
  • Public claims: Custom claims registered in the IANA JWT Claims Registry to avoid collisions.
  • Private claims: Custom claims agreed upon between the issuer and consumer.

Common registered claims and what they mean:

{
"sub": "1234567890", // Subject: who the token refers to (usually user ID)
"iss": "myapp.com", // Issuer: who created the token
"aud": "api.myapp", // Audience: who the token is intended for
"exp": 1716000000, // Expiry: Unix timestamp when the token expires
"iat": 1715996400, // Issued At: Unix timestamp when the token was created
"nbf": 1715996400, // Not Before: token is invalid before this time
"jti": "abc123" // JWT ID: unique identifier for this token
}

The Signature

The signature is what makes JWTs trustworthy. It is created by taking the encoded header, a dot, the encoded payload, then signing that string using the algorithm and secret key specified in the header.

HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)

If anyone tampers with the header or payload after the token is issued, the signature becomes invalid. The server detects this on verification and rejects the token.

Important: Decoding a JWT only reads the header and payload. It does not verify a signature. Building one with the Encode tab signs it with the algorithm and secret you choose. Only a server holding the correct secret (or public key, for asymmetric algorithms) can verify that a token is authentic.

Is a JWT Decoded or Decrypted?

A huge number of developers search for how to "decrypt" a JWT token, but strictly speaking, a standard JWT is never encrypted in the first place, so there is nothing to decrypt. It is Base64URL encoded, which is a reversible text transformation, not a cipher. That is why this tool (and every other JWT tool) decodes a token rather than decrypting it.

Here is the distinction that trips people up:

  • Encoding / decoding: Turns JSON into a compact, URL-safe string and back again. No key is required in either direction. Anyone can decode the header and payload of any JWT.
  • Signing / verifying: Proves the token has not been tampered with, using a secret (HS256/384/512) or a private/public key pair (RS256, ES256). This is what most people actually mean when they say "decrypt."
  • Encrypting / decrypting: Hides the payload contents so nobody but the intended recipient can read them. Standard JWTs (technically JWS, JSON Web Signature) skip this step entirely. Only JWE (JSON Web Encryption), a separate and much less common token format, actually encrypts the payload and requires a real decryption key to read it.

So if your token looks like the typical three-part xxxxx.yyyyy.zzzzz string, it is a signed JWT, not an encrypted one, and this Decode tab will show you the full payload instantly with no password, secret, or private key needed.

How to Decode a JWT in Any Language

This tool is the fastest way to inspect a token by hand, but most of the time you will decode a JWT from inside your own code. Every mainstream language has a library that does this in one or two lines. In every case below, decoding reads the header and payload without needing a secret; verifying a signature is a separate step that does require one.

JavaScript (browser)

You can decode a JWT with nothing but built-in browser APIs, exactly how this tool works internally:

function decodeJWT(token) {
  const payload = token.split('.')[1];
  const json = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
  return JSON.parse(json);
}

For a battle-tested drop-in instead, the jwt-decode npm package handles Base64URL padding, malformed tokens, and header decoding for you:

import { jwtDecode } from 'jwt-decode';

const decoded = jwtDecode(token); // payload
const header = jwtDecode(token, { header: true }); // header

This same package is used under the hood by countless React, Angular, and Vue projects, since decoding a JWT is purely client-side JSON parsing with no framework-specific logic involved. Flutter apps typically reach for a dedicated Dart package instead, such as jwt_decoder, which works the same way: no secret needed, just a call like JwtDecoder.decode(token) to get the claims back as a map.

Node.js

The popular jsonwebtoken package (the same one used in the encode example further down) can decode a token without verifying it by passing the complete option:

const jwt = require('jsonwebtoken');

const decoded = jwt.decode(token, { complete: true });
console.log(decoded.header); // { alg: 'HS256', typ: 'JWT' }
console.log(decoded.payload); // your claims

Python

The standard approach uses PyJWT with signature verification turned off, covered step by step in our JWT Token Structure guide. If your project uses python-jose instead (common in FastAPI and OIDC setups), the equivalent inspect-only call is jwt.get_unverified_claims(token), which skips the key requirement entirely rather than passing an option to disable it.

Java and Spring Boot

Spring Security ships a class literally named JwtDecoder. The most common implementation, NimbusJwtDecoder, verifies against a JWK set and returns the parsed claims in one call:

JwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
Jwt jwt = decoder.decode(token);
Map<String, Object> claims = jwt.getClaims();

Outside Spring, most plain-Java projects reach for the jjwt library, which has a similarly fluent parser API for reading claims from a token.

PHP

The firebase/php-jwt package (installed via composer require firebase/php-jwt) decodes and verifies in the same call:

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$decoded = JWT::decode($jwt, new Key($secret, 'HS256'));

Only need to peek at the header or payload without a key? The manual base64_decode() / json_decode() approach for that case is covered in the JWT Token Structure guide.

C# / .NET

System.IdentityModel.Tokens.Jwt is the standard library here too, walked through in our JWT Token Structure guide. One detail worth knowing: ReadJwtToken() reads the claims but never touches the signature, so it will happily "decode" a token signed with a key you don't have, or even one with a deliberately corrupted signature. Reach for ValidateToken() instead the moment you need to trust the result rather than just inspect it.

Other Ways to Decode a JWT

Besides pasting a token into a web tool, developers commonly reach for one of these:

  • Browser DevTools console: paste the one-liner from the JavaScript example above directly into the console for a quick, no-install decode while debugging a network request.
  • Command line: jwt-cli (install via brew install mike-engel/jwt-cli/jwt-cli or Cargo) decodes a token with a single jwt decode <token> command, which is handy for piping tokens straight out of curl or jq. A quick manual alternative with tools you likely already have is echo $TOKEN | cut -d '.' -f2 | base64 -d | jq, though you may need to swap in base64 -D on macOS and convert the Base64URL characters (- and _) first for a clean decode.
  • Code editor extensions: several editor marketplaces have JWT-decoding extensions that let you select a token in a file and see the decoded claims inline, without leaving the editor.

How to Encode (Generate) a JWT

Use the Encode tab to build and sign your own token, entirely in your browser:

  1. Edit the Header JSON, usually you only need to leave typ: "JWT" as is
  2. Edit the Payload JSON with the claims you want, sub, exp, and any custom fields
  3. Choose a signing Algorithm: this also sets the alg field in the header automatically
  4. Enter a Secret Key: the token signs itself as you type
  5. Copy the result and use it for testing an API, seeding a database, or debugging an auth flow

The signature is computed using the browser's native crypto.subtle.sign() Web Crypto API. No external library is loaded and no data is sent anywhere.

Choosing a Signing Algorithm

AlgorithmHashKey typeNotes
HS256SHA-256Shared secretMost common default, supported everywhere
HS384SHA-384Shared secretLonger signature, rarely required
HS512SHA-512Shared secretLonger signature, rarely required
RS256SHA-256RSA private/public key pairNot supported here, sign server-side
ES256SHA-256ECDSA private/public key pairNot supported here, sign server-side

Asymmetric algorithms (RS256, ES256) exist so that one service can sign with a private key while many other services verify with the matching public key, without ever sharing the private key. That setup belongs on a server, not in a browser tool, which is why this encoder only supports the HMAC family.

Equivalent Code in Node.js

The token this tool generates is identical to what a backend library would produce. For reference, here is the same operation using the popular jsonwebtoken package:

const jwt = require('jsonwebtoken');

const token = jwt.sign(
  { sub: '1234567890', name: 'John Doe' },
  'your-256-bit-secret',
  { algorithm: 'HS256', expiresIn: '1h' }
);

JWT vs Session Tokens

The key difference between JWTs and traditional session tokens is where the data lives:

  • Session tokens: A random string that maps to session data stored server-side (in a database or cache). Every request requires a database lookup.
  • JWTs: All the data the server needs is embedded in the token itself. No database lookup needed. This makes JWTs ideal for stateless APIs and microservices.

The tradeoff: JWTs cannot be easily invalidated before expiry since the server holds no state. Session tokens can be deleted from the database immediately to log a user out.

JWT Acronym and Pronunciation

JWT stands for JSON Web Token. It is pronounced either as individual letters ("J-W-T") or as the word "jot." Both are widely accepted. The standard is defined in RFC 7519, published by the IETF.

What JWT Tokens Are Used For

  • Authentication: Verifying a user's identity after login. The most common use case.
  • Authorization: Encoding roles and permissions so the server can make access control decisions without a database call.
  • Information exchange: Passing verified data between services in a microservice architecture.
  • Single Sign-On (SSO): Sharing authentication across multiple domains or services.

Security: What Not to Put in a JWT

Because the payload is only Base64 encoded (not encrypted), anyone holding the token can read its contents. Never include sensitive data in a JWT payload:

  • Passwords or password hashes
  • Credit card numbers or financial data
  • Personal identification numbers (SSN, passport, etc.)
  • Private keys or API secrets

If you need to transmit sensitive data in a token, use JWE (JSON Web Encryption), which encrypts the payload, rather than plain JWT.

How to Use This Tool

Not sure where to find a token to paste in? A JWT usually turns up in one of these places: a session or auth cookie in your browser's DevTools (Application tab), a localStorage entry after logging in to a web app, or the value after Bearer in an Authorization request header. Copy just the token string (the three dot-separated parts), not the cookie name or the word "Bearer" itself.

Decoding a token:

  1. Paste any JWT token into the text area on the Decode tab
  2. The decoder splits the token at the dots and decodes each part
  3. The Header shows the algorithm and token type
  4. The Payload shows all claims including expiry as a readable date
  5. The Signature is shown raw. It cannot be decoded without the secret key

Encoding a token:

  1. Switch to the Encode tab
  2. Edit the header and payload JSON to match what you need
  3. Pick an algorithm and enter a secret key
  4. Copy the generated token from the result box

Frequently Asked Questions

What does JWT stand for?

JWT stands for JSON Web Token. It is an open standard (RFC 7519) for representing claims securely between two parties using a compact, URL-safe string format.

What is a JWT access token?

A JWT access token is a JWT used to grant access to protected API resources. It is issued by an authorization server after successful login and typically has a short expiry time (minutes to hours). It is sent in the HTTP Authorization header as a Bearer token on API requests.

What is the JWT payload?

The JWT payload is the middle section of the token. It contains claims: JSON key-value pairs that carry information about the user, permissions, and token validity period. It is Base64URL encoded, not encrypted, so it can be read by anyone with the token.

What is a JWT signing key?

The signing key is the secret used to create the token's signature. For symmetric algorithms like HS256, it is a shared secret known to both the issuer and verifier. For asymmetric algorithms like RS256, the issuer signs with a private key and verifiers check using the corresponding public key.

Can I verify a JWT signature with this tool?

The Decode tab does not verify signatures, since that requires the secret key. If you know the secret a token was signed with, switch to the Encode tab, rebuild the same header and payload, sign it with that secret, and compare the result to the original token. If they match, the signature is valid.

Are expired JWTs still decodable?

Yes. Expiry (the exp claim) is just a number inside the payload. Decoding reads the payload regardless of whether the token has expired. Expiry is only enforced during signature verification on the server. The server checks the exp value and rejects expired tokens. This decoder shows you the expiry date so you can see if a token has expired.

How do I create or encode a JWT online?

Switch to the Encode tab, edit the header and payload JSON, choose a signing algorithm (HS256, HS384, or HS512), and enter a secret key. The tool builds and signs the token entirely in your browser using the Web Crypto API and updates the result as you type.

What algorithm should I use to sign a JWT?

HS256 is the most common choice for symmetric signing and is supported by virtually every JWT library. Use HS384 or HS512 only if you have a specific requirement for a longer hash output. Asymmetric algorithms like RS256 or ES256 use a private and public key pair instead of a shared secret and are not supported by this browser-based encoder, sign those on your server.

Is it safe to enter my real secret key into this tool?

Signing happens entirely client-side using the Web Crypto API. Your secret key is never sent to any server or logged anywhere. That said, for production secrets it is still good practice to use a throwaway or test secret rather than your live signing key whenever possible.

Can I decode a JWT without knowing the secret key?

Yes, and that is exactly what happens when you paste a token into the Decode tab above: no key field appears anywhere on that tab because none is needed. You only need a key on the Encode tab, where it is used to produce a signature, not to unlock anything on the way in.

Is a JWT encrypted or just encoded?

A standard JWT is encoded, not encrypted. The header and payload are Base64URL encoded JSON, which anyone can reverse without a key, and then signed to prove they have not been tampered with. If you need the contents themselves hidden from anyone who intercepts the token, you need JWE (JSON Web Encryption) instead, which is a different, less common token format.

What is the difference between decoding and decrypting a JWT?

Decoding reverses the Base64URL encoding to reveal the JSON header and payload; it needs no key and works on any well-formed token. Decrypting removes real encryption to reveal hidden contents; it needs a decryption key and only applies to JWE tokens, not standard signed JWTs. Most people who search for how to "decrypt" a JWT actually just want to decode it, which is exactly what the Decode tab above does.

Does this JWT decoder work offline?

Yes. Decoding and encoding both happen entirely in your browser using JavaScript and the Web Crypto API, so once the page has loaded, no token or secret is ever sent over the network. You can disconnect from the internet and the tool keeps working exactly the same.

Is this a good alternative to jwt.io?

For everyday decoding and HMAC signing, yes. It covers the same core workflow, pasting a token to see its header and payload, and building a signed HS256, HS384, or HS512 token from scratch, entirely client-side. The main difference is scope: this tool focuses on the HMAC family for browser-based signing, while jwt.io also supports verifying and signing with asymmetric algorithms like RS256 and ES256, which need a private key and are better handled server-side anyway.