Decoding a JWT access token means splitting the compact header.payload.signature string into its three segments and turning the first two — the header and payload — from Base64url-encoded UTF-8 into readable JSON objects. The third segment, the signature, is checked only for its compact shape; its bytes are never interpreted as a successful signature, so a decoded payload is information about what the token says, not proof that the token is authentic. A JSON Web Token (JWT) is a small, signed JSON object used by APIs and identity providers to carry claims about a logged-in user or client, and an access token is the specific JWT that authorizes API calls. To inspect one locally, paste it into a browser-based JWT Decoder; the tool runs the Base64url decode and JSON parse on the same machine you are reading this from, never uploads the token, and labels every successful result as unverified so a quick inspection is not mistaken for a security check.

how to decode jwt access token
how to decode jwt access token

What Decoding a JWT Access Token Actually Does

A JSON Web Token in compact serialization is just three Base64url-encoded strings joined by dots. The header describes the token's signing algorithm and sometimes a key identifier; the payload holds the claims that the issuer wants the receiving service to read; the signature is the cryptographic proof that the header and payload were not changed after the token was issued. An access token is the specific JWT that an OAuth 2.0 or OpenID Connect flow hands to a client application so the client can call a protected API on behalf of a user. Decoding one means taking the compact form, splitting it on the dots, and translating the first two segments back into UTF-8 JSON. It does not involve any cryptographic operation; the signature segment is only checked for its compact shape.

RFC 7519 defines this three-segment representation as compact JWS serialization. RFC 7519 also lists the registered claims that a decoder can recognize by name. RFC 4648 defines the Base64url alphabet that the segments use — the URL-safe version of Base64 that replaces '+' with '-' and '/' with '_' and normally omits the '=' padding you see in standard Base64. A practical decoder therefore has to accept those substitutions and reject padded strings rather than silently accepting a different format.

Why Decode Locally Instead of Pasting Into a Random Online Site

An access token frequently carries information you do not want to leak. Even when it does not contain a password, it can carry a user identifier, an email, a tenant ID, scopes, role names, session metadata, or an internal customer number. Sending that string to an unfamiliar web service is equivalent to handing the keys to whoever runs the service, the analytics vendor they integrate with, the browser extensions installed on that page, and any logs they retain. Privacy-friendly tools do the opposite: the JWT Decoder decodes entirely in the browser, never makes a network request for the token, does not fetch a signing key, does not write a copy anywhere, and does not require an account. The page is a single static interface that splits the string on dots and runs Base64url decoding plus JSON parsing locally.

This matters in development as well as in production debugging. A token pasted into a chat thread, a screenshot, or a public paste site can be replayed against the API it was issued for as long as it has not expired and as long as the audience matches. Local decoding keeps the token visible only to you, on your screen, for as long as you keep the page open, which makes it appropriate for the routine inspection work every backend developer eventually needs to do.

How to Decode a JWT Access Token in Three Steps

  1. Open the JWT Decoder page in your browser and paste a compact JWT in the standard header.payload.signature form. Make sure you are pasting the whole token — three Base64url segments separated by two dots — with no extra whitespace, no surrounding quotes, and no newline characters around the dots.
  2. Select Decode JWT. The page splits the string on the dots, checks that there are exactly three segments, validates that the first two use the unpadded RFC 4648 Base64url alphabet, decodes each as UTF-8, and parses the result as a JSON object. The third segment is checked only for its compact Base64url shape; its bytes are never interpreted as a successful signature.
  3. Read the header and payload panels. The decoder lists every present RFC 7519 registered claim — issuer, subject, audience, expiration time, not-before time, issued-at time, and JWT ID — alongside the raw JSON so you can also see any private claim names the application uses. The page marks every successful decode as unverified; close the page or clear the input when you are done so the token does not remain visible.

If the tool reports an error rather than a decode, the most common causes are a missing or extra segment, padded Base64 characters that do not belong to the URL-safe alphabet, a header or payload that is not valid JSON, or invalid UTF-8 inside one of the decoded segments. Fix the source token in the issuing application and try again — do not attempt to repair a token by hand.

Reading the Decoded Header and Payload

The header is almost always a small object with an alg field that names the signing algorithm — HS256, RS256, ES256, and so on — and optionally a typ, kid, or cty field. If the alg value is "none", the token is unsecured and the third segment is empty; treat such tokens as untrusted even after a successful decode. The payload is where the application-specific and standard claims live.

ClaimFull nameMeaning in an access token
issIssuerThe party that minted the token; should match the issuing authority of your API.
subSubjectThe principal the token represents — usually a user ID or service account.
audAudienceThe intended recipient; a string or array of strings that should include your API identifier.
expExpiration timeUnix seconds after which the token must not be accepted.
nbfNot beforeUnix seconds before which the token must not be accepted.
iatIssued atUnix seconds at which the token was minted.
jtiJWT IDA unique identifier for the token; useful for replay defense.

Custom claims appear alongside the registered ones and can carry anything the issuer chooses — tenant, role, scope, internal flags, or feature toggles. The decoder surfaces them as part of the raw payload so they remain visible without assigning them special meaning. JWT also allows a private namespace for claims that begin with a registered prefix but resolve to an application-specific value; treat those as untrusted until the issuing service documents them.

Decode vs Verify: Why a Readable Payload Is Not Proof

The most common mistake when reading an access token is treating the decoded JSON as evidence that the token is valid. Decoding and verification are two different operations. Decoding translates the first two segments from Base64url to JSON; verification checks the signature against a known key, confirms the issuer and audience match your service, enforces the expiration policy, and only then decides whether to honor the token. A local decoder can only do the first half.

This means a successfully decoded access token can still be forged, expired, issued for a different application, signed by a key your service does not trust, or replayed after logout. It can also be a token whose signature was checked in a different system and now lives in a developer's clipboard. A readable payload describes what the token claims about its bearer; it does not prove that the bearer is who the token says. Whenever trust matters, run validation in the authentication library and key-management flow of the application that issued the token, using the issuer, audience, algorithm, key, and clock-skew policy that service actually enforces.

Inspecting Timestamp Claims in an Access Token

The exp, nbf, and iat claims are NumericDate values: the number of seconds since the Unix epoch, ignoring leap seconds. Because raw integer seconds are awkward to scan in a developer console, the JWT Decoder shows each present timestamp as both the raw value and an ISO 8601 string, so a ten-digit number reads as the matching UTC instant at a glance. The ISO text is a reading aid, not a guarantee — whether the timestamp is acceptable depends on the issuing system, its configured clock skew, its intended audience, and the validation policy that service applies.

ClaimTypeWhat the page showsWhat you still need to check
expNumericDateRaw seconds and ISO timestampWhether the issuing system's clock skew and expiry policy still consider it current
nbfNumericDateRaw seconds and ISO timestampWhether the current time is past nbf under the issuer's clock skew
iatNumericDateRaw seconds and ISO timestampWhether the token's age matters for the application policy

This is the reason an access token that decodes cleanly can still be rejected at the API gateway: the gateway enforces the timestamp, your local decoder does not. Treat the timestamp values you read as information about the issuer's intent, not as a verdict on the token's current acceptability. For cross-checks outside the JWT context, a Unix Timestamp Converter can convert the same NumericDate into UTC, your local time zone, or an ISO 8601 string without sending the value anywhere.