JWT Decode & Sign API

Decode any JWT, check expiry and verify its signature with a secret, PEM or JWK – or sign new tokens with HS256/384/512, RS, PS or ES algorithms.

POSThttps://apibox.io.vn/v1/jwt
Security & Crypto▶ Try it online

The JWT API decodes, verifies and creates JSON Web Tokens. In decode mode (the default) you send a token – a leading Bearer is stripped – and get its header and payload as JSON, plus human-readable claims: issued_at, expires_at and not_before as ISO dates, and whether the token is expired or not_yet_valid.

Add a secret (HMAC shared secret, or an RSA/EC public key as PEM PUBLIC KEY or JWK) and the signature is verified too: signature_valid tells you if the signature matches and valid is true only when the signature is correct and the token is within its validity window. Supported algorithms: HS256/384/512, RS256/384/512, PS256/384/512 and ES256/384/512.

In sign mode (action=sign, or simply send a payload) the API builds a signed token from your JSON payload with the chosen algorithm (default HS256) and secret (an HMAC secret, or a PKCS#8 PRIVATE KEY PEM / private JWK for asymmetric algorithms). expires_in (seconds) adds iat and exp claims for you. The endpoint is POST-only so tokens and keys never appear in URLs.

Parameters

NameInTypeRequiredDefault
actionbodystringnodecodedecode or sign. Defaults to sign when a payload is sent.
tokenbodystringnodecode: the JWT to decode (a Bearer prefix is accepted).
secretbodystringnoHMAC secret, or a PEM / JWK key (public key to verify, PKCS#8 private key to sign). Alias key for decode. Required for sign.
payloadbodyobjectnosign: JSON object of claims (or a JSON string).
algorithmbodystringnoHS256sign: HS256/384/512, RS256/384/512, PS256/384/512, ES256/384/512.
expires_inbodynumbernosign: lifetime in seconds; adds iat and exp claims.

Example

curl -X POST "https://apibox.io.vn/v1/jwt" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3OTQyODczMTQsImV4cCI6MTc5NDI5MDkxNCwic3ViIjoidXNlcl8xMjMiLCJyb2xlIjoiYWRtaW4ifQ.Dle3BtqLL449n-RirNMbP23azwGNJ57klSgX2-x1rH4","secret":"my-secret"}'

Response

{
  "header": {
    "alg": "HS256",
    "typ": "JWT"
  },
  "payload": {
    "iat": 1794287314,
    "exp": 1794290914,
    "sub": "user_123",
    "role": "admin"
  },
  "claims": {
    "issued_at": "2026-11-10T05:08:34.000Z",
    "expires_at": "2026-11-10T06:08:34.000Z",
    "not_before": null,
    "expired": false,
    "not_yet_valid": false
  },
  "signature_valid": true,
  "valid": true
}

Use cases

  • Debug authentication by inspecting the claims of an access token
  • Check why a token is rejected: expired, not yet valid or bad signature
  • Create test tokens for local development and integration tests
  • Verify tokens from third-party identity providers with their public key

FAQ

Is it safe to paste my token here?

The token and secret are processed in memory on Cloudflare Workers and not stored. Still, treat production secrets with care: prefer test tokens, and rotate any secret you suspect has been exposed.

How do I verify an RS256 token?

POST {"token": "eyJ...", "secret": "-----BEGIN PUBLIC KEY-----..."}. A public key in JWK format (a JSON object string) also works. The algorithm is read from the token header.

Why is "valid" null in the response?

Because no secret or key was given, so the signature could not be checked. The token was only decoded; signature_valid and valid are null until you provide a key.

Related APIs

Start with 1,000 free requests every month. Get free API key →