Back to Help Center
DEVELOPER September 11, 2026 · 5 min read

How to Decode a JWT Token (Step-by-Step)

JWTs are three base64url-encoded segments joined with dots. Anyone can decode them — no key needed. Use a decoder or split-and-decode manually.

Decoding a JWT reveals the header and payload as JSON. No key needed — JWT payloads are base64-encoded, not encrypted. Anyone can decode.

Prerequisites

  • The JWT token string (typically the value of an Authorization: Bearer header)

Method 1 — Use the JWT Decoder

Paste the token into the JWT decoder. Get:

  • Decoded header (algorithm, key ID, token type)
  • Decoded payload (claims: sub, iss, aud, exp, iat, custom claims)
  • Signature format (not verified — decoding ≠ verifying)

Method 2 — Command Line

Split the token on dots into three segments:

TOKEN="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.abc..."
HEADER=$(echo $TOKEN | cut -d. -f1)
PAYLOAD=$(echo $TOKEN | cut -d. -f2)

echo $HEADER | base64 -d
echo $PAYLOAD | base64 -d

Note: base64url uses - and _ instead of + and /, and drops padding. Add padding to make it valid classic base64:

pad() { local a=$1; while [ $(( ${#a} % 4 )) -ne 0 ]; do a="${a}="; done; echo $a; }
echo $(pad $HEADER) | tr '_-' '/+' | base64 -d

Convert with the Base64 converter for a UI approach.

Method 3 — Python

import base64, json

def decode_jwt_segment(seg):
    # Add padding
    seg += '=' * (4 - len(seg) % 4)
    # Base64url → base64
    seg = seg.replace('-', '+').replace('_', '/')
    return json.loads(base64.b64decode(seg))

token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.abc..."
header, payload, _ = token.split('.')
print(decode_jwt_segment(header))
print(decode_jwt_segment(payload))

What You Get

Header — always metadata:

{
  "alg": "HS256",
  "typ": "JWT",
  "kid": "2024-key-1"
}

Payload — claims:

{
  "sub": "user-42",
  "iss": "https://auth.example.com",
  "aud": "https://api.example.com",
  "exp": 1735689600,
  "iat": 1735686000,
  "role": "admin"
}

Decoding ≠ Verifying

Decoding reveals the payload. It does not verify the signature. A tampered token decodes fine but has an invalid signature. See how to verify a JWT signature for the verification step.

Common Miss

  • Assuming decoded payload is safe — anyone can craft a valid-looking payload; always verify signature server-side
  • Trying to decode the third segment (signature) as base64 → it’s a binary signature, not JSON
  • Confusing base64url with classic base64 — the - / _ substitutions matter

Read what a JWT is for the full structure explanation.

Read what a JWT is, check the JWT glossary entry, and see the JWS entry for signature-format details.