v0.0.1 · system status
Open APIOpenAPI 3.1Zero token storage

Inspect token

Decode a JWT structure without verifying its signature or claims.

POST /v1/inspect/token Decode a JWT structure without verifying its signature or claims.

Decode the header, payload, and signature segment of a JWT and report any suspicious structural patterns. Decoding does not verify trust — see /v1/validate/jwt for that.

Decoded ≠ validated

The response always carries validated: false and a warning string to that effect. Use this endpoint for fixtures, logs, debugging, and pre-validation pattern detection. Never use the decoded payload as an authorization input.

Request

body — application/json
Field Type Required Description
token string yes The JWT to decode. Three base64url-encoded segments separated by dots. The leading Bearer prefix is not stripped server-side; trim it client-side. Minimum length 1.

Response — 200

body — application/json
Field Type Required Description
decoded.header object yes The decoded JWT header as a JSON object.
decoded.payload object yes The decoded JWT payload as a JSON object.
decoded.signature_segment string yes The raw signature segment (base64url, undecoded). Echoed for debugging only — verification belongs in /v1/validate/jwt.
validated boolean yes Always false. This endpoint does not validate.
warning string yes Human-readable disclaimer that decoded ≠ validated. Echoed unchanged on every response.
suspicious_warnings string[] yes Codes detected by structural inspection. See Suspicious patterns below.
200 successful decode of an HS256 token with no suspicious patterns
{
  "decoded": {
    "header": {
      "alg": "HS256",
      "typ": "JWT",
      "kid": "k1"
    },
    "payload": {
      "sub": "usr_1",
      "exp": 9999999999
    },
    "signature_segment": "KJ2lp..."
  },
  "validated": false,
  "warning": "Token was decoded only. Decoded does not mean validated: signature, issuer, audience, and claim policy were not checked.",
  "suspicious_warnings": []
}

Suspicious patterns

suspicious_warnings returns codes for any of the following structural risks. Each one is documented in Errors with detection rules and remediation guidance.

CodeTrigger
ALG_NONEheader.alg == "none" (exact, case-sensitive).
JKU_PRESENTjku field present in header. Indicates a token whose key resolution would fetch from an arbitrary URL on naïve verifiers.
KID_MISSINGNo kid in header. Operationally fragile during JWKS rotation.
EXP_MISSINGNo exp in payload. Token has no expiry.

Detection is key-presence based, not truthiness. A token whose exp claim is 0 is expired, not missing exp; it surfaces as TOKEN_EXPIRED from /v1/validate/jwt, not as a suspicious warning here.

Errors

StatusCodeCause
400MALFORMED_TOKENToken is not a parseable JWT (wrong segment count, invalid base64url, non-JSON header/payload, header/payload not a JSON object).
422Request body missing the token field, or token is empty.
// 400
{
  "error": {
    "code": "MALFORMED_TOKEN",
    "message": "expected 3 segments, got 1"
  }
}

Examples

inspect_token.sh
curl -sSf -X POST "$JWTSHIELD_URL/v1/inspect/token" \
-H "Authorization: Bearer $JWTSHIELD_KEY" \
-H "Content-Type: application/json" \
-d '{"token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3JfMSJ9.x"}'
inspect_token.js
const KEY = process.env.JWTSHIELD_KEY;
const r = await fetch(`${BASE_URL}/v1/inspect/token`, {
method: "POST",
headers: {
  "Authorization": `Bearer ${KEY}`,
  "Content-Type": "application/json",
},
body: JSON.stringify({ token }),
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const body = await r.json();
console.log(body.decoded.header, body.suspicious_warnings);
inspect_token.py
KEY = os.environ["JWTSHIELD_KEY"]
r = httpx.post(
  f"{BASE_URL}/v1/inspect/token",
  headers={"Authorization": f"Bearer {KEY}"},
  json={"token": token},
  timeout=10.0,
)
r.raise_for_status()
body = r.json()
print(body["decoded"]["header"], body["suspicious_warnings"])