Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

Common actions

Discover how to manage users using SuperTokens.

Overview

SuperTokens exposes a set of functions and APIs that you can use to have manual control over your users. Actions like fetching users or deleting them are available through different SDK calls.


Get user

By email

import supertokens from "supertokens-node";

async function getUserInfo() {
  let usersInfo = await supertokens.listUsersByAccountInfo("public", {
    email: "test@example.com",
  });

  /**
   *
   * userInfo contains the following info:
   * - emails
   * - id
   * - timeJoined
   * - tenantIds
   * - phone numbers
   * - third party login info
   * - all the login methods associated with this user.
   * - information about if the user's email is verified or not.
   *
   */
}
import (
	"fmt"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)

func main() {

	// Note that usersInfo has type User[]
	// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
	userInfo, err := emailpassword.GetUserByEmail("public", "test@example.com")
	if err != nil {
		// TODO: Handle error
		return
	}
	fmt.Println(userInfo)
	//...
}
from supertokens_python.asyncio import list_users_by_account_info
from supertokens_python.types.base import AccountInfoInput


async def some_func():
    # Note that users_info has type List[User]
    user_info = await list_users_by_account_info("public", AccountInfoInput(email="test@example.com"))
    print(user_info)

    #
    # user_info contains the following info:
    # - emails
    # - id
    # - timeJoined
    # - tenantIds
    # - phone numbers
    # - third party login info
    # - all the login methods associated with this user.
    # - information about if the user's email is verified or not.
    #
from supertokens_python.syncio import list_users_by_account_info
from supertokens_python.types.base import AccountInfoInput


def some_func():
    # Note that users_info has type List[User]
    user_info = list_users_by_account_info("public", AccountInfoInput(email="test@example.com"))
    print(user_info)

    #
    # user_info contains the following info:
    # - emails
    # - id
    # - timeJoined
    # - tenantIds
    # - phone numbers
    # - third party login info
    # - all the login methods associated with this user.
    # - information about if the user's email is verified or not.
    #

By phone number

import supertokens from "supertokens-node";

async function handler() {
  let usersInfo = await supertokens.listUsersByAccountInfo("public", {
    phoneNumber: "+1234567890",
  });

  /**
   *
   * userInfo contains the following info:
   * - emails
   * - id
   * - timeJoined
   * - tenantIds
   * - phone numbers
   * - third party login info
   * - all the login methods associated with this user.
   * - information about if the user's email is verified or not.
   *
   */
}
import (
	"fmt"

	"github.com/supertokens/supertokens-golang/recipe/passwordless"
)

func main() {

	tenantId := "public"
	userInfo, err := passwordless.GetUserByPhoneNumber(tenantId, "+1234567890")
	if err != nil {
		// TODO: Handle error
		return
	}
	fmt.Println(userInfo)
	//...
}
from supertokens_python.asyncio import list_users_by_account_info
from supertokens_python.types.base import AccountInfoInput


async def some_func():
    _ = await list_users_by_account_info(
        "public", AccountInfoInput(phone_number="+1234567890")
    )
from supertokens_python.syncio import list_users_by_account_info
from supertokens_python.types.base import AccountInfoInput


def some_func():
    _ = list_users_by_account_info(
        "public", AccountInfoInput(phone_number="+1234567890")
    )

By User ID

Next.js router
import express from "express";
import { verifySession } from "supertokens-node/recipe/session/framework/express";
import { SessionRequest } from "supertokens-node/framework/express";
import supertokens from "supertokens-node";

let app = express();
app.get("/get-user-info", verifySession(), async (req: SessionRequest, res) => {
  let userId = req.session!.getUserId();

  let userInfo = await supertokens.getUser(userId);

  /**
   *
   * userInfo contains the following info:
   * - emails
   * - id
   * - timeJoined
   * - tenantIds
   * - phone numbers
   * - third party login info
   * - all the login methods associated with this user.
   * - information about if the user's email is verified or not.
   *
   */
});
import { verifySession } from "supertokens-node/recipe/session/framework/hapi";
import Hapi from "@hapi/hapi";
import { SessionRequest } from "supertokens-node/framework/hapi";
import supertokens from "supertokens-node";

let server = Hapi.server({ port: 8000 });

server.route({
  path: "/get-user-info",
  method: "get",
  options: {
    pre: [
      {
        method: verifySession(),
      },
    ],
  },
  handler: async (req: SessionRequest, res) => {
    let userId = req.session!.getUserId();

    let userInfo = await supertokens.getUser(userId);

    /**
     *
     * userInfo contains the following info:
     * - emails
     * - id
     * - timeJoined
     * - tenantIds
     * - phone numbers
     * - third party login info
     * - all the login methods associated with this user.
     * - information about if the user's email is verified or not.
     *
     */
  },
});
import Fastify from "fastify";
import { verifySession } from "supertokens-node/recipe/session/framework/fastify";
import { SessionRequest } from "supertokens-node/framework/fastify";
import supertokens from "supertokens-node";

const fastify = Fastify();

fastify.post(
  "/like-comment",
  {
    preHandler: verifySession(),
  },
  async (req: SessionRequest, res) => {
    let userId = req.session!.getUserId();

    let userInfo = await supertokens.getUser(userId);

    /**
     *
     * userInfo contains the following info:
     * - emails
     * - id
     * - timeJoined
     * - tenantIds
     * - phone numbers
     * - third party login info
     * - all the login methods associated with this user.
     * - information about if the user's email is verified or not.
     *
     */
  },
);
import { verifySession } from "supertokens-node/recipe/session/framework/awsLambda";
import { SessionEvent } from "supertokens-node/framework/awsLambda";
import supertokens from "supertokens-node";

async function getUserInfo(awsEvent: SessionEvent) {
  let userId = awsEvent.session!.getUserId();

  let userInfo = await supertokens.getUser(userId);

  /**
   *
   * userInfo contains the following info:
   * - emails
   * - id
   * - timeJoined
   * - tenantIds
   * - phone numbers
   * - third party login info
   * - all the login methods associated with this user.
   * - information about if the user's email is verified or not.
   *
   */
}

exports.handler = verifySession(getUserInfo);
import KoaRouter from "koa-router";
import { verifySession } from "supertokens-node/recipe/session/framework/koa";
import { SessionContext } from "supertokens-node/framework/koa";
import supertokens from "supertokens-node";

let router = new KoaRouter();

router.get("/get-user-info", verifySession(), async (ctx: SessionContext, next) => {
  let userId = ctx.session!.getUserId();

  let userInfo = await supertokens.getUser(userId);

  /**
   *
   * userInfo contains the following info:
   * - emails
   * - id
   * - timeJoined
   * - tenantIds
   * - phone numbers
   * - third party login info
   * - all the login methods associated with this user.
   * - information about if the user's email is verified or not.
   *
   */
});
import { inject, intercept } from "@loopback/core";
import { RestBindings, MiddlewareContext, get, response } from "@loopback/rest";
import { verifySession } from "supertokens-node/recipe/session/framework/loopback";
import Session from "supertokens-node/recipe/session";
import { SessionContext } from "supertokens-node/framework/loopback";
import supertokens from "supertokens-node";

class GetUserInfo {
  constructor(@inject(RestBindings.Http.CONTEXT) private ctx: MiddlewareContext) {}
  @get("/get-user-info")
  @intercept(verifySession())
  @response(200)
  async handler() {
    let userId = ((this.ctx as any).session as Session.SessionContainer).getUserId();

    let userInfo = await supertokens.getUser(userId);

    /**
     *
     * userInfo contains the following info:
     * - emails
     * - id
     * - timeJoined
     * - tenantIds
     * - phone numbers
     * - third party login info
     * - all the login methods associated with this user.
     * - information about if the user's email is verified or not.
     *
     */
  }
}
import { Controller, Post, UseGuards, Request, Response } from "@nestjs/common";
import { AuthGuard } from "./auth/auth.guard";
import { Session } from "./auth/session.decorator";
import { SessionRequest } from "supertokens-node/framework/express";
import supertokens from "supertokens-node";

@Controller()
export class ExampleController {
  @Post("example")
  @UseGuards(new AuthGuard()) // For more information about this guard please read our NestJS guide.
  async postExample(
    @Request() req: SessionRequest,
    @Session() session: Session,
    @Response({ passthrough: true }) res: Response,
  ): Promise<boolean> {
    let userId = session.getUserId();

    let userInfo = await supertokens.getUser(userId);

    /**
     *
     * userInfo contains the following info:
     * - emails
     * - id
     * - timeJoined
     * - tenantIds
     * - phone numbers
     * - third party login info
     * - all the login methods associated with this user.
     * - information about if the user's email is verified or not.
     *
     */
    return true;
  }
}
import (
	"fmt"
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)

func main() {
	_ = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
		session.VerifySession(nil, getUserInfoAPI).ServeHTTP(rw, r)
	})
}

func getUserInfoAPI(w http.ResponseWriter, r *http.Request) {
	sessionContainer := session.GetSessionFromRequestContext(r.Context())

	userID := sessionContainer.GetUserID()
	// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
    userInfo, err := emailpassword.GetUserByID(userID)
	if err != nil {
		// TODO: Handle error
		return
	}
	fmt.Println(userInfo)
}
import (
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)

func main() {
	router := gin.New()
	router.GET("/getuserinfo", verifySession(nil), getUserInfoAPI)
}

func verifySession(options *sessmodels.VerifySessionOptions) gin.HandlerFunc {
	return func(c *gin.Context) {
		session.VerifySession(options, func(rw http.ResponseWriter, r *http.Request) {
			c.Request = c.Request.WithContext(r.Context())
			c.Next()
		})(c.Writer, c.Request)
		// we call Abort so that the next handler in the chain is not called, unless we call Next explicitly
		c.Abort()
	}
}

func getUserInfoAPI(c *gin.Context) {
	sessionContainer := session.GetSessionFromRequestContext(c.Request.Context())

	userID := sessionContainer.GetUserID()

	// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
    userInfo, err := emailpassword.GetUserByID(userID)
	if err != nil {
		// TODO: Handle error
		return
	}
	fmt.Println(userInfo)
	//...
}
import (
	"fmt"
	"net/http"

	"github.com/go-chi/chi"
	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)

func main() {
	r := chi.NewRouter()
	r.Get("/getuserinfo", session.VerifySession(nil, getUserInfoAPI))
}

func getUserInfoAPI(w http.ResponseWriter, r *http.Request) {
	sessionContainer := session.GetSessionFromRequestContext(r.Context())

	userID := sessionContainer.GetUserID()
	// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
	userInfo, err := emailpassword.GetUserByID(userID)
	if err != nil {
		// TODO: Handle error
		return
	}
	fmt.Println(userInfo)
}
import (
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/emailpassword"
)

func main() {
	router := mux.NewRouter()
	router.HandleFunc("/getuserinfo", session.VerifySession(nil, getUserInfoAPI)).Methods(http.MethodGet)
}

func getUserInfoAPI(w http.ResponseWriter, r *http.Request) {
	sessionContainer := session.GetSessionFromRequestContext(r.Context())

	userID := sessionContainer.GetUserID()
	// You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
	userInfo, err := emailpassword.GetUserByID(userID)
	if err != nil {
		// TODO: Handle error
		return
	}
	fmt.Println(userInfo)
}
from fastapi import Depends, FastAPI

from supertokens_python.asyncio import get_user
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.fastapi import verify_session

app = FastAPI()

@app.post('/get_user_info_api')
async def get_user_info_api(session: SessionContainer = Depends(verify_session())):
    user_id = session.get_user_id()

    # You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
    _ = await get_user(user_id)
from flask import Flask, g

from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.flask import verify_session
from supertokens_python.syncio import get_user

app = Flask(__name__)

@app.route('/get_user_info', methods=['GET'])
@verify_session()
def get_user_info_api():
    session: SessionContainer = g.supertokens

    user_id = session.get_user_id()

    # You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
    _ = get_user(user_id)
from typing import cast

from django.http import HttpRequest

from supertokens_python.asyncio import get_user
from supertokens_python.recipe.session import SessionContainer
from supertokens_python.recipe.session.framework.django.asyncio import verify_session


@verify_session()
async def get_user_info_api(request: HttpRequest):
    session: SessionContainer = cast(SessionContainer, request.supertokens)

    user_id = session.get_user_id()

    # You can learn more about the `User` object over here https://github.com/supertokens/core-driver-interface/wiki
    _ = await get_user(user_id)

Using the user metadata recipe

Checkout the user metadata recipe docs which shows you how to save and fetch any JSON object against the user’s ID. You can use this to save information like the user’s name (first_name and last_name) or any other field associated with the user.


Delete user

import { deleteUser } from "supertokens-node";

async function deleteUserForId() {
  let userId = "..."; // get the user ID
  await deleteUser(userId); // this will succeed even if the userId didn't exist.
}
import "github.com/supertokens/supertokens-golang/supertokens"

func main() {
	userId := "..." // get the user ID somehow...
	supertokens.DeleteUser(userId) // this will succeed even if the userId didn't exist.
}
from supertokens_python.asyncio import delete_user


async def do_delete():
    user_id = "..." # get the user ID somehow...
    await delete_user(user_id) # this will succeed even if the userId didn't exist.
from supertokens_python.syncio import delete_user


user_id = "..." # get the user ID somehow...
delete_user(user_id) # this will succeed even if the userId didn't exist.

List users

Newest first

import { getUsersNewestFirst } from "supertokens-node";

async function getUsers() {
  // get the latest 100 users
  let usersResponse = await getUsersNewestFirst({
    tenantId: "public",
  });

  let users = usersResponse.users;
  let nextPaginationToken = usersResponse.nextPaginationToken;

  // get the next 200 users
  usersResponse = await getUsersNewestFirst({
    tenantId: "public",
    limit: 200,
    paginationToken: nextPaginationToken,
  });

  users = usersResponse.users;
  nextPaginationToken = usersResponse.nextPaginationToken;

  // get for specific recipes
  usersResponse = await getUsersNewestFirst({
    tenantId: "public",
    limit: 200,
    paginationToken: nextPaginationToken,
    // only get for those users who signed up with <RECIPE_NAME>
    includeRecipeIds: ["<RECIPE_ID>"],
  });

  users = usersResponse.users;
  nextPaginationToken = usersResponse.nextPaginationToken;
}
import "github.com/supertokens/supertokens-golang/supertokens"

func main() {
	// get the latest 100 users
	result, err := supertokens.GetUsersNewestFirst("", nil, nil, nil, nil)
	if err != nil {
		// TODO: Handle error
		return
	}

	// get the next 200 users
	limit := 200
	result, err = supertokens.GetUsersNewestFirst("", result.NextPaginationToken, &limit, nil, nil)
	if err != nil {
		// TODO: Handle error
		return
	}

	// get for specific recipes
	includeRecipeIds := []string{"<RECIPE_ID>"}
	result, err = supertokens.GetUsersNewestFirst("", result.NextPaginationToken, &limit, &includeRecipeIds, nil)
	if err != nil {
		// TODO: Handle error
		return
	}
}
from supertokens_python.asyncio import get_users_newest_first


async def some_func():
	# get the latest 100 users
	users_response = await get_users_newest_first("public")

	# get the next 200 users
	users_response = await get_users_newest_first("public", 200, users_response.next_pagination_token)

	# get for specific recipes
	users_response = await get_users_newest_first(
		"public",
		200,
		users_response.next_pagination_token,
		# only get for those users who signed up with <RECIPE_NAME>
		["<RECIPE_ID>"]
	)
from supertokens_python.syncio import get_users_newest_first


# get the latest 100 users
users_response = get_users_newest_first("public")

# get the next 200 users
users_response = get_users_newest_first("public", 200, users_response.next_pagination_token)

# get for specific recipes
users_response = get_users_newest_first(
	"public",
	200,
	users_response.next_pagination_token,
	# only get for those users who signed up with <RECIPE_NAME>
	["<RECIPE_ID>"]
)

Oldest first

import { getUsersOldestFirst } from "supertokens-node";

async function getUsers() {
  // get the latest 100 users
  let usersResponse = await getUsersOldestFirst({
    tenantId: "public",
  });
  let users = usersResponse.users;
  let nextPaginationToken = usersResponse.nextPaginationToken;

  // get the next oldest 200 users
  usersResponse = await getUsersOldestFirst({
    tenantId: "public",
    limit: 200,
    paginationToken: nextPaginationToken,
  });

  users = usersResponse.users;
  nextPaginationToken = usersResponse.nextPaginationToken;

  // get for specific recipes
  usersResponse = await getUsersOldestFirst({
    tenantId: "public",
    limit: 200,
    paginationToken: nextPaginationToken,
    // only get for those users who signed up with <RECIPE_NAME>
    includeRecipeIds: ["<RECIPE_ID>"],
  });

  users = usersResponse.users;
  nextPaginationToken = usersResponse.nextPaginationToken;
}
import "github.com/supertokens/supertokens-golang/supertokens"

func main() {
	// get the oldest 100 users
	result, err := supertokens.GetUsersOldestFirst("", nil, nil, nil, nil)
	if err != nil {
		// TODO: Handle error
		return
	}

	// get the next oldest 200 users
	limit := 200
	result, err = supertokens.GetUsersOldestFirst("", result.NextPaginationToken, &limit, nil, nil)
	if err != nil {
		// TODO: Handle error
		return
	}

	// get for specific recipes
	includeRecipeIds := []string{"<RECIPE_ID>"}
	result, err = supertokens.GetUsersOldestFirst("", result.NextPaginationToken, &limit, &includeRecipeIds, nil)
	if err != nil {
		// TODO: Handle error
		return
	}
}
from supertokens_python.asyncio import get_users_oldest_first


async def some_func():
	# get the latest 100 users
	users_response = await get_users_oldest_first("public")

	# get the next 200 users
	users_response = await get_users_oldest_first("public", 200, users_response.next_pagination_token)

	# get for specific recipes
	users_response = await get_users_oldest_first(
		"public",
		200,
		users_response.next_pagination_token,
		# only get for those users who signed up with <RECIPE_NAME>
		["<RECIPE_ID>"]
	)
from supertokens_python.syncio import get_users_oldest_first


# get the latest 100 users
users_response = get_users_oldest_first("public")

# get the next 200 users
users_response = get_users_oldest_first("public", 200, users_response.next_pagination_token)

# get for specific recipes
users_response = get_users_oldest_first(
	"public",
	200,
	users_response.next_pagination_token,
	# only get for those users who signed up with <RECIPE_NAME>
	["<RECIPE_ID>"]
)
  • If the nextPaginationToken is undefined, then there are no more users to loop through.
  • If there are no users in your app, then nextPaginationToken is undefined and users is an empty array
  • Each element in the users array is according to the output of the core API as shown in the API documentation.
  • If the result.NextPaginationToken is nil, then there are no more users to loop through.
  • If there are no users in your app, then result.NextPaginationToken is nil and result.Users is an empty array
  • Each element in the result.Users array is according to the output of the core API as shown in the API documentation.

Count users

import { getUserCount } from "supertokens-node";

async function getCount() {
  let count = await getUserCount();
}
import (
	"fmt"

	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	tenantId := ""
	count, err := supertokens.GetUserCount(nil, &tenantId)
	if err != nil {
		// TODO: Handle error
		return
	}

	fmt.Println(count)
}
from supertokens_python.asyncio import get_user_count


async def some_func():
    user_count = await get_user_count()

    print(user_count) # TODO..
from supertokens_python.syncio import get_user_count


user_count = get_user_count()

API reference

API schema and response details