Clerk logo

Clerk Docs

Ctrl + K
Go to clerk.devGet API keys

Getting started with Node SDK

Installation

There's an ES module for the Clerk Node SDK available under the @clerk/clerk-sdk-node npm package. Use `npm` or `yarn` to install the Clerk Node module.

1
npm install @clerk/clerk-sdk-node
1
yarn add @clerk/clerk-sdk-node

Set CLERK_API_KEY

The Node SDK will pick automatically the CLERK_API_KEY vale from your environment variables. If your application is using .env files, create a file named .env.local in your application root, if it doesn't exist already, and add the below variable:

.env.local
CLERK_API_KEY=test_asdf1234

Make sure you update this variable with the API key found in your Clerk instance dashboard under API Keys

Resource types

The following types are of interest to the integrator:

ResourceDescription
Clientunique browser or mobile app
Sessiona session for a given user on a given client
Usera person signed up via Clerk
Emailan email message sent to another user
SMS Messagean SMS message sent to another user

The following types are not directly manipulable but can be passed as params to applicable calls:

ResourceDescriptionUsage
EmailAddressemail address, a user may have a primary & several secondaryemail address id can be provided to `emails` sub-api to specify the recipient
PhoneNumberE.164 telephone number, a user may have a primary & several secondaryphone number id can be provided to `smsMessages` sub-api to specify the recipient

Internal implementation details

This SDK is written in TypeScript and built with tsdx.

CJS, ESM, and UMD module builds are provided.

The http client used by the sdk is got.

All resource operations are mounted as sub-APIs on a Clerk class and return promises that either resolve with their expected resource types or reject with the error types described below.

The sub-APIs are also importable directly if you don't want to go through the Clerk class.

Available options and ENV vars

The following options are available for you to customize the behaviour of the Clerk class.

Note that most options can also be set as ENV vars so that you don't need to pass anything to the constructor or set it via the available setters.

OptionDescriptionDefaultENV variable
apiKeyserver key for api.clerk.devnone`CLERK_API_KEY`
apiVersionfor future use, v1 for now"v1"`CLERK_API_VERSION`
serverApiURLfor debugging / future use"https://api.clerk.dev"`CLERK_API_URL`
httpOptionshttp client options{}N/A

For every option the resolution is as follows, in order of descending precedence:

  1. option passed
  2. ENV var (if applicable)
  3. default

Another available environment variable is CLERK_LOGGING.

You can set its value to true to enable additional logging that may be of use when debugging an issue.

httpOptions

The SDK allows you to pass options to the underlying http client (got) by instantiating it with an additional httpOptions object.

e.g. to pass a custom header:

const sdk = new Clerk(apiKey, {
httpOptions: {
headers: { "x-unicorn": "rainbow" }
}
});

You can check the options the got client supports here.

Singleton

If you are comfortable with setting the CLERK_API_KEY ENV variable and be done with it, the default instance created by the SDK will suffice for your needs.

ESM

import clerk from '@clerk/clerk-sdk-node';
const userList = await clerk.users.getUserList();

Or if you are interested only in a certain resource:

import { sessions } from '@clerk/clerk-sdk-node';
const sessionList = await sessions.getSessionList();

CJS

const pkg = require('@clerk/clerk-sdk-node');
const clerk = pkg.default;
clerk.emails
.createEmail({ fromEmailName, subject, body, emailAddressId })
.then((email) => console.log(email))
.catch((error) => console.error(error));

Or if you prefer a resource sub-api directly:

const pkg = require('@clerk/clerk-sdk-node');
const { clients } = pkg;
clients
.getClient(clientId)
.then((client) => console.log(client))
.catch((error) => console.error(error));

Setters

The following setters are available for you to change the options even after you've obtained a handle on a Clerk or sub-api instance:

If you have a clerk handle:

  • clerk.apiKey = value;
  • clerk.serverApiUrl = value;
  • clerk.apiVersion = value;
  • clerk.httpOptions = value;

If are using a sub-api handle and wish to change options on the (implicit) singleton Clerk instance:

  • setClerkApiKey(value)
  • setClerkServerApiUrl(value)
  • setClerkApiVersion(value)
  • setClerkHttpOptions(value)

Custom instantiation

If you would like to use more than one Clerk instance, e.g. if you are using multiple API keys or simply prefer the warm fuzzy feeling of controlling instantiation yourself:

ESM

import Clerk from '@clerk/clerk-sdk-node/instance';
const clerk = new Clerk({ apiKey: 'top-secret' });
const clientList = await clerk.clients.getClientList();

CJS

const Clerk = require('@clerk/clerk-sdk-node/instance').default;
const clerk = new Clerk({ apiKey: 'your-eyes-only' });
clerk.smsMessages
.createSMSMessage({ message, phoneNumberId })
.then((smsMessage) => console.log(smsMessage))
.catch((error) => console.error(error));

Multi-session applications

If Clerk is running in multi-session mode, it's important to ensure your frontend sends the Session ID that is making the request.

Our middleware will look for a query string parameter named _clerk_session_id. If this parameter is not found, the middleware will instead choose the last active session, which may be subject to race conditions and should not be relied on for authenticating actions.

Node.js middleware

Optional session

This strategy allows you to detect whether or not there's an active session, and handle each case separately.

1
import { withAuth } from '@clerk/clerk-sdk-node';
2
3
function handler(req, res) {
4
if (req.session) {
5
// do something with session.userId
6
} else {
7
// Respond with 401 or similar
8
}
9
}
10
11
export default withAuth(handler);
1
import { withAuth, WithAuthProp } from '@clerk/clerk-sdk-node';
2
3
function handler(req: WithAuthProp<NextApiRequest>, res: NextApiResponse) {
4
if (req.session) {
5
// do something with session.userId
6
} else {
7
// Respond with 401 or similar
8
}
9
}
10
11
export withAuth(handler);

Required session

This strategy mandates that a session be available. If not, it returns a 401 (no body) and your handler is never called.

1
import { requireAuth } from '@clerk/clerk-sdk-node';
2
3
function handler(req, res) {
4
// do something with session.userId
5
}
6
7
export default requireAuth(handler)
1
import { requireAuth, RequireAuthProp } from '@clerk/clerk-sdk-node';
2
3
function handler(req: RequireAuthProp<NextApiRequest>, res: NextApiResponse) {
4
// do something with session.userId
5
}
6
7
export default requireAuth(handler)

Manual authentication

Authenticate a particular session

Highly recommended for authenticating actions.

import { sessions } from '@clerk/clerk-sdk-node';
import Cookies from 'cookies';
// Retrieve the particular session ID from a
// query string parameter
const sessionId = req.query._clerk_session_id;
// Note: Clerk stores the clientToken in a cookie
// named "__session" for Firebase compatibility
const cookies = new Cookies(req, res);
const clientToken = cookies.get('__session');
const session = await sessions.verifySession(sessionId, clientToken);

Authenticate the last active session

Using the last active session is appropriate when determining the user after a navigation.

import { clients, sessions } from '@clerk/clerk-sdk-node';
// Note: Clerk stores the clientToken in a cookie
// named "__session" for Firebase compatibility
const cookies = new Cookies(req, res);
const clientToken = cookies.get('__session');
const client = await clients.verifyClient(sessionToken);
const sessionId = client.lastActiveSessionId;
const session = await sessions.verifySession(sessionId, clientToken);

Was this helpful?

Clerk © 2022