Developer Debug Bundle
Decode a JWT, format an API response, and read a Base64 header without pasting any of it into someone else’s server.
Step-by-step recipe
Decode the token
Paste the token from the Authorization header. A leading “Bearer ” is fine; the decoder drops it. You get the header, the payload, and, if the token has an exp claim, a line saying when it expired or will expire. The signature is not checked.
Format the API response
Paste the response body and press Format. It comes back indented with two spaces. If the JSON is broken, you get the line and column where parsing stopped.
Decode auth headers
Paste the value after “Basic ” and press Decode to see the username:password pair it carries. Works on any standard Base64 header or cookie value.
Why the steps run in this order
- Start with the token, because an expired token is the usual suspect behind a sudden 401. The decoder tells you right away if exp is in the past. If it is, you’re done: refresh the token and retry.
- Then read the error body. Many APIs say exactly what’s wrong, like a missing scope or the wrong audience, in a JSON body that arrives as one long line. Formatting it takes a second and saves you squinting at a wall of braces.
- Check the Base64 header last. If the token looks fine and the body is vague, the client may be sending the wrong credentials altogether. Decoding a Basic header shows you which user it actually logs in as.
- Skip any step that doesn’t apply. The three tools don’t depend on each other. The order is just the one that finds the usual causes fastest.
- Do all of it locally. A production token is a live credential until it expires. Pasting it into a decoder that runs on someone else’s server puts that credential in their request logs.
Worked example: A 401 from your own API
Your frontend gets 401 Unauthorized from GET /api/orders. It worked yesterday, and nothing in the orders code changed.
- In DevTools, open the failed request and copy the Authorization header value. You can paste it with “Bearer ” still in front.
- Paste it into the JWT Decoder. The status line says “Expires in 52 minutes”, so the token is still live. The payload shows "aud": "orders-api-staging".
- Copy the response body into the JSON Formatter and press Format. The body is below.
{
"error": "invalid_token",
"error_description": "audience mismatch"
}Result: The frontend was built with the staging auth settings, so its tokens name the staging API as their audience. Fix the environment variable and redeploy. The token never left your browser.
What it won’t do
- The JWT Decoder does not verify signatures. A decoded token tells you what it claims, not who issued it. Check signatures on your server with the real key.
- Only exp gets a human-readable label. Other dates, like iat and nbf, show as raw Unix timestamps in seconds.
- The Base64 Converter reads standard Base64. URL-safe Base64 uses - and _ instead of + and /, so swap those two characters before you decode.
- The JSON Formatter needs strict JSON. Trailing commas, comments, and single-quoted strings are errors.
Tips for best results
- In Chrome DevTools, right-click a header and use “Copy value”. Selecting by hand often grabs the header name too.
- The expiry line uses your computer’s clock. If a token you just got looks expired, check your clock and the issuing server’s.
- On a Mac, ⌘ Enter in the JSON Formatter formats without reaching for the mouse.
- If you already pasted a live token into a server-side decoder, rotate it.
Questions
Is it safe to paste a production JWT here?
The decoding runs in your browser and the token isn’t sent anywhere. Still treat it like a password: don’t paste it into tickets, chat, or screenshots, and clear the field when you’re done.
Why does the decoder say “signature not verified”?
Checking a signature needs the issuer’s secret or public key, and this tool doesn’t ask for one. Anyone can create a token with any payload. Decoding shows you what a token says, not whether it’s genuine.
My token won’t decode. What’s wrong?
Usually extra text or a cut-off paste. A JWT is three Base64URL parts joined by two dots. If the tool says a JWT must contain exactly 3 parts, the copy is incomplete. If it fails on valid-looking input, check for quotes around it or a stray character from the copy. A “Bearer ” prefix and line breaks are removed for you.
What does a Basic auth header decode to?
“Basic dXNlcjpwYXNz” decodes to user:pass. Base64 is encoding, not encryption. Anyone who sees the header can read the password, which is why Basic auth should only travel over HTTPS.
Can I squash formatted JSON back to one line?
Yes. Press Minify in the JSON Formatter. It strips all whitespace, which is handy for pasting a fixture into a test or a curl command.