A JWT decoder can quickly reveal why an API request is failing, but decoding is only the first step. This guide presents a safe, repeatable workflow for inspecting JSON Web Token headers and claims, checking expiration and audience values, verifying signatures, and handing useful evidence to the right debugging tools without exposing production credentials.
Overview
JSON Web Tokens are compact strings commonly used to carry authentication and authorization data between an identity provider, a client, and an API. A typical JWT has three dot-separated parts: a header, a payload, and a signature.
xxxxx.yyyyy.zzzzz
The header usually identifies the token type and signing algorithm. The payload contains claims such as the issuer, subject, audience, issued-at time, and expiration time. The signature allows a verifier to check whether the token was created by a trusted signer and whether its signed content has changed.
A JWT decoder or a small local script can decode the header and payload because those sections use Base64URL encoding. Decoding does not decrypt the token and does not prove that it is authentic. Anyone who obtains a JWT can often read its encoded header and payload, so tokens should never contain information that the application cannot safely expose to the token holder.
Keep this distinction in mind when debugging:
- Decode: Convert the header and payload into readable JSON.
- Inspect: Compare claims with the request, environment, and API configuration.
- Validate: Check the token's signature, issuer, audience, time claims, and expected algorithm using trusted verification code or an identity provider's tooling.
The most useful workflow moves from low-risk inspection to controlled verification. Avoid pasting live production tokens into public online developer tools unless your organization's security rules explicitly allow it.
Step-by-step workflow
1. Capture the failure and preserve context
Start with the complete API response, status code, request URL, method, and environment. Record whether the failure is a 401 Unauthorized, a 403 Forbidden, or an application-level error. These responses can point to different problems, but the status alone is not proof of the cause.
Also note which token was sent, without copying the token into a ticket, chat channel, or issue tracker. A redacted fingerprint or the token's non-sensitive metadata can help correlate requests while reducing exposure.
2. Decode the header and payload locally
Use a local JWT decoder, an approved command-line utility, or a short script to split the token at its periods and Base64URL-decode the first two sections. Inspect the resulting JSON for unexpected values, malformed data, or a token from the wrong environment.
For example, a header may resemble:
{
"typ": "JWT",
"alg": "RS256",
"kid": "key-identifier"
}
A payload might include:
{
"iss": "https://identity.example",
"sub": "user-123",
"aud": "orders-api",
"iat": 1710000000,
"exp": 1710003600,
"scope": "orders:read"
}
The values above are illustrative. Your service's expected issuer, audience, scopes, and time behavior must come from its own configuration and documentation.
3. Check time-based claims
Compare exp with the current time and check nbf if present. Confirm whether the client, API, and identity provider have a sensible clock relationship. A token can appear valid to one system and expired to another when clocks differ or when a long-running process continues using an old token.
Also check iat. An issued-at time far in the future can indicate clock skew, a bad conversion between seconds and milliseconds, or a token created in the wrong environment. Do not edit a claim in a decoded payload and expect the token to become valid: changing signed content invalidates the original signature.
4. Check issuer, audience, and permissions
The iss claim identifies the token issuer, while aud identifies the intended recipient. Compare both with the API's configured values, including scheme, host, tenant, and environment where relevant. A development token sent to a staging API, or a token intended for one service sent to another, can fail even when the user is authenticated.
Next, inspect claims such as scope, roles, or permissions. A valid token may still be rejected because it does not grant the operation being requested. This distinction helps separate authentication problems from authorization problems.
5. Verify the signature with trusted configuration
Signature verification requires the appropriate secret or public key, the expected algorithm, and the issuer's key configuration. Use the API's normal authentication library or an approved identity-provider tool rather than treating a decoder's visual output as validation.
For asymmetric signing, the header's kid may identify which public key should be used. If verification fails, check key rotation, key discovery configuration, cached key data, algorithm allowlists, and whether the token was copied or truncated. Never resolve a verification error by accepting arbitrary algorithms or disabling signature checks.
6. Reproduce with a controlled request
After forming a hypothesis, reproduce the request with a fresh token in a local or non-production environment. Compare the working and failing requests header by header. Confirm that the authorization scheme is correct, the token is not being altered by a proxy or frontend interceptor, and the API receives the same token that the client generated.
Tools and handoffs
Different tools answer different questions. A JWT decoder is useful for readable header and payload inspection. An API client or browser network panel shows what was actually sent. Application logs can reveal which validation check failed, provided they do not record raw tokens. Identity-provider logs can help confirm issuance, audience, scopes, and key selection. The API's authentication middleware is the final authority on what the service accepts.
For a repeatable local setup, keep a small debugging collection with redacted example tokens, expected claim values, and requests for each environment. Pair it with the local API workflow described in How to Create a Fast Local Debugging Toolkit for API Development. If you are comparing several browser-based utilities, use the same security rule you would apply to other online developer tools for quick debugging: public or synthetic data is safer than live credentials.
When handing the issue to another developer, include the status code, environment, redacted claim summary, expected versus observed issuer and audience, relevant timestamps, key identifier, and verification error. Do not include the bearer token itself. If accidental exposure is suspected, follow the team's credential-revocation process rather than relying on deletion from a message or clipboard.
Quality checks
- Token structure: Confirm there are three sections and that the header and payload decode as valid JSON.
- Encoding: Treat the decoded output as readable data, not decrypted or trusted data.
- Time: Check
exp,nbf, andiatagainst the service's clock and documented tolerance. - Identity: Compare
issandaudwith the API's configured expectations. - Authorization: Confirm scopes, roles, or permissions cover the requested operation.
- Signature: Verify with trusted keys and an explicit algorithm policy.
- Transport: Confirm the client sends the intended token using the correct authorization header and that intermediaries do not modify it.
- Secrecy: Remove tokens from logs, screenshots, shell history, support tickets, and shared online tools.
These checks also make useful automated tests. Test expired tokens, wrong audiences, unknown issuers, missing scopes, invalid signatures, rotated keys, and modest clock differences. A decoder helps you understand the fixture; the validation tests establish the behavior you can rely on.
When to revisit
Revisit this JWT debugging workflow whenever the identity provider, API gateway, authentication library, signing algorithm, key-rotation process, or claim mapping changes. It is also worth reviewing after a migration between development, staging, and production, because issuer and audience mismatches often appear at environment boundaries.
Update your local examples and run the validation checks after changing token lifetimes, scopes, role names, clock-tolerance settings, or public-key discovery. Review the safety guidance when your team adopts a new browser-based JWT decoder, API client, logging platform, or AI-assisted developer tool. The practical next step is to create a redacted test token, document the expected claims for each environment, and verify one successful and one intentionally failing request. That small reference gives future debugging sessions a reliable starting point without requiring anyone to handle a live credential.