JWT encoder / decoder

Paste a token to read its header and payload, or sign one from your own claims — no button, no upload.

Optional while decoding (fill it in to verify), required to sign.

How to use it

  1. Paste a token: the header and payload appear at once, with no button to press. Anything that came from the token stays exactly as it was signed — the input is never rewritten.
  2. Add the secret below the input to check the signature. Leaving it empty simply means “not verified”: you still read the claims as they are.
  3. Switch to Encode, write your claims as JSON, pick HS256/384/512 and a secret, and copy the token that comes out. Switching mode never clears what you typed.
  4. Standard exp / iat / nbf claims are spelled out in your own language and time zone, with expired and not-yet-valid marks.

Example

Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1LTEwMjQiLCJuYW1lIjoiSmFuZSBDb29wZXIiLCJyb2xlIjoiZWRpdG9yIiwiaXNzIjoiaHR0cHM6Ly9hcGkuZXhhbXBsZS5jb20iLCJpYXQiOjE3NjcyMjU2MDAsImV4cCI6MTc5ODc2MTYwMH0.jCqliF6m-TAglXcHrjuXj7kYIjjsRO7kv6_8O1yb_7Q

Header and payload

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

Payload
{
  "sub": "u-1024",
  "name": "Jane Cooper",
  "role": "editor",
  "iss": "https://api.example.com",
  "iat": 1767225600,
  "exp": 1798761600
}

Signed with the secret “dev-secret-change-me”; type it into Secret and the status line changes to “Signature verified”. Switch to Encode and press Sample to get the same payload: with the same secret it rebuilds this exact token, character for character.

Rules, limits and known issues

  • Only HS256, HS384 and HS512 are supported, for signing and for verifying. RS*, ES* and PS* tokens are decoded and shown as-is, but their signature is never checked — that needs a public key, so the status line says so instead of guessing.
  • Unsigned tokens (alg: none) are decoded and clearly flagged, but never produced: asking to sign without a secret gives an error rather than an unsigned token.
  • Encoding builds the header itself (`{"alg": … ,"typ": "JWT"}`). Header fields such as kid, jku, x5c or cty are not carried over — this tool signs claims, not certificate chains.
  • Your claims JSON is re-serialised compactly before signing, so indentation and comments stay out of the token. Key order follows JavaScript objects: repeated keys collapse to the last one, and numeric-looking keys move to the front.
  • Very large integers lose precision — `12345678901234567890` comes back rounded, because that is what JavaScript numbers do. Nothing is silently corrected; use strings when exact digits matter.
  • The claims are shown indented for reading, while the signature covers the raw segments exactly as they appear in the token. Nothing is re-encoded behind your back, so a token that verifies here also verifies in your own code.
  • Base64url is strict: `+`, `/` and `=` are reported as errors instead of being quietly accepted, and bytes that are not UTF-8 are reported rather than replaced with replacement characters. Whitespace inside a pasted token is ignored, since tokens never contain any.
  • Encrypted JWEs (five parts) are not decrypted — you get told that is what you pasted.
  • Size limit 10,000 characters. Nothing is uploaded, stored, written to the URL or shared: the share button only shares this page address, never your token or secret.

Once you have read the claims, these are the usual next steps.