Skip to main content

Modifying JWT claims

Adding custom claims to the JWT during creation#

When using the JWT feature you can add custom claims to the JWT by using our override feature.

import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";

supertokens: {
connectionURI: "...",
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
recipeList: [
jwt: {
enable: true,
override: {
functions: function (originalImplementation) {
return {
createNewSession: async function (input) {
input.accessTokenPayload = {
role: "user",

return originalImplementation.createNewSession(input);

The above example would add a role claim to the JWT.

Default claims added by SuperTokens#

SuperTokens adds some claims to JWT payloads:

  • sub: The userId is stored in this claim
  • iss: The issuer URL is stored under this claim. Read more here for information on what the default value is and how to configure it.
  • exp: The time since epoch (in seconds) after which the JWT is considered as expired
  • iat: The time since epoch (in seconds) when the JWT was created

Updating claims of the JWT post creation#

Another method to add custom claims is to use the mergeIntoAccessTokenPayload function. This allows you to add / edit / delete claims in the JWT even after it is created.

Method 1) After session verification#

import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";

let app = express();"/updateinfo", verifySession(), async (req, res) => {

let session = req.session;

await session.mergeIntoAccessTokenPayload(
{ newKey: "newValue" }

res.json({ message: "successfully updated access token payload" })
  • We first require session verification in order to get the session object
  • Using that object, we call the mergeIntoAccessTokenPayload with new content.
  • If for a key, you set a value to null / nil / None when using this function, then that key-value will be removed from the payload if it existed.
  • The result is that the access token payload is updated in the database and in the user's browser cookies. The change is instantly visible on the frontend and the subsequent backend API calls.

Method 2) Without session verification#


Changes to the access token payload via this method are reflected in the session only once the session is refreshed. So use method (1) whenever possible.

import Session from "supertokens-node/recipe/session";

async function updateJWT() {
let userId = "...";
// we first get all the sessionHandles (string[]) for a user
let sessionHandles = await Session.getAllSessionHandlesForUser(userId);

// we update all the session's Access Token payloads for this user
sessionHandles.forEach(async (handle) => {
let currSessionInfo = await Session.getSessionInformation(handle)
if (currSessionInfo === undefined) {

await Session.mergeIntoAccessTokenPayload(handle,
{ newKey: "newValue" }