openapi: 3.0.3
info:
title: Clerk Backend Account Portal Users API
x-logo:
url: https://clerk.com/_next/image?url=%2Fimages%2Fclerk-logo.svg&w=96&q=75
altText: Clerk docs
href: https://clerk.com/docs
contact:
email: support@clerk.com
name: Clerk Platform Team
url: https://clerk.com/support
description: 'The Clerk REST Backend API, meant to be accessed by backend servers.
### Versions
When the API changes in a way that isn''t compatible with older versions, a new version is released.
Each version is identified by its release date, e.g. `2025-04-10`. For more information, please see [Clerk API Versions](https://clerk.com/docs/versioning/available-versions).
Please see https://clerk.com/docs for more information.'
version: '2025-11-10'
termsOfService: https://clerk.com/terms
license:
name: MIT
url: https://github.com/clerk/openapi-specs/blob/main/LICENSE
servers:
- url: https://api.clerk.com/v1
security:
- bearerAuth: []
tags:
- name: Users
description: The user object represents a user that has successfully signed up to your application.
externalDocs:
url: https://clerk.com/docs/references/javascript/user
paths:
/users:
get:
operationId: GetUserList
x-speakeasy-group: users
x-speakeasy-name-override: list
summary: List All Users
description: 'Returns a list of all users.
The users are returned sorted by creation date, with the newest users appearing first.'
tags:
- Users
parameters:
- name: email_address
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the specified email addresses.
Accepts up to 100 email addresses.
Any email addresses not found are ignored.'
required: false
- name: phone_number
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the specified phone numbers.
Accepts up to 100 phone numbers.
Any phone numbers not found are ignored.'
required: false
- name: external_id
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the specified external IDs.
For each external ID, the `+` and `-` can be
prepended to the ID, which denote whether the
respective external ID should be included or
excluded from the result set.
Accepts up to 100 external IDs.
Any external IDs not found are ignored.'
required: false
- name: username
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the specified usernames.
Accepts up to 100 usernames.
Any usernames not found are ignored.'
required: false
- name: web3_wallet
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the specified web3 wallet addresses.
Accepts up to 100 web3 wallet addresses.
Any web3 wallet addresses not found are ignored.'
required: false
- name: user_id
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the user IDs specified.
For each user ID, the `+` and `-` can be
prepended to the ID, which denote whether the
respective user ID should be included or
excluded from the result set.
Accepts up to 100 user IDs.
Any user IDs not found are ignored.'
required: false
- name: organization_id
in: query
schema:
type: array
items:
type: string
description: 'Returns users that have memberships to the
given organizations.
For each organization ID, the `+` and `-` can be
prepended to the ID, which denote whether the
respective organization should be included or
excluded from the result set.
Accepts up to 100 organization IDs.'
required: false
- name: query
in: query
description: 'Returns users that match the given query.
For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user IDs, first and last names.
The query value doesn''t need to match the exact value you are looking for, it is capable of partial matches as well.'
schema:
type: string
required: false
- name: email_address_query
in: query
description: 'Returns users with emails that match the given query, via case-insensitive partial match.
For example, `email_address_query=ello` will match a user with the email `HELLO@example.com`.'
schema:
type: string
required: false
- name: phone_number_query
in: query
description: 'Returns users with phone numbers that match the given query, via case-insensitive partial match.
For example, `phone_number_query=555` will match a user with the phone number `+1555xxxxxxx`.'
schema:
type: string
required: false
- name: username_query
in: query
description: 'Returns users with usernames that match the given query, via case-insensitive partial match.
For example, `username_query=CoolUser` will match a user with the username `SomeCoolUser`.'
schema:
type: string
- name: name_query
in: query
description: Returns users with names that match the given query, via case-insensitive partial match.
schema:
type: string
- name: banned
in: query
required: false
description: Returns users which are either banned (`banned=true`) or not banned (`banned=false`).
schema:
type: boolean
- name: last_active_at_before
in: query
description: 'Returns users whose last session activity was before the given date (with millisecond precision).
Example: use 1700690400000 to retrieve users whose last session activity was before 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: last_active_at_after
in: query
description: 'Returns users whose last session activity was after the given date (with millisecond precision).
Example: use 1700690400000 to retrieve users whose last session activity was after 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: last_active_at_since
in: query
deprecated: true
description: 'Returns users that had session activity since the given date.
Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day.
Deprecated in favor of `last_active_at_after`.'
example: 1700690400000
schema:
type: integer
- name: created_at_before
in: query
description: 'Returns users who have been created before the given date (with millisecond precision).
Example: use 1730160000000 to retrieve users who have been created before 2024-10-29.'
example: 1730160000000
schema:
type: integer
- name: created_at_after
in: query
description: 'Returns users who have been created after the given date (with millisecond precision).
Example: use 1730160000000 to retrieve users who have been created after 2024-10-29.'
example: 1730160000000
schema:
type: integer
- name: last_sign_in_at_before
in: query
description: 'Returns users whose last sign-in was before the given date (with millisecond precision).
Example: use 1700690400000 to retrieve users whose last sign-in was before 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: last_sign_in_at_after
in: query
description: 'Returns users whose last sign-in was after the given date (with millisecond precision).
Example: use 1700690400000 to retrieve users whose last sign-in was after 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: provider
in: query
schema:
type: string
description: 'Returns users with external accounts for the specified OAuth provider.
Must be used in combination with the `provider_user_id` parameter.
For example, use `provider=oauth_google&provider_user_id=12345` to retrieve a user with Google provider user ID 12345.'
required: false
- name: provider_user_id
in: query
schema:
type: array
items:
type: string
description: 'Returns users with the specified provider user IDs for a specific provider.
Must be used in combination with the `provider` parameter.
For example, use `provider=oauth_google&provider_user_id=12345` to retrieve a user with Google provider user ID 12345.
Accepts up to 100 provider user IDs.
Any provider user IDs not found are ignored.'
required: false
- $ref: '#/components/parameters/LimitParameter'
- $ref: '#/components/parameters/OffsetParameter'
- name: order_by
in: query
description: 'Allows to return users in a particular order.
At the moment, you can order the returned users by their `created_at`,`updated_at`,`email_address`,`web3wallet`,`first_name`,`last_name`,`phone_number`,`username`,`last_active_at`,`last_sign_in_at`.
In order to specify the direction, you can use the `+/-` symbols prepended in the property to order by.
For example, if you want users to be returned in descending order according to their `created_at` property, you can use `-created_at`.
If you don''t use `+` or `-`, then `+` is implied. We only support one `order_by` parameter, and if multiple `order_by` parameters are provided, we will only keep the first one. For example,
if you pass `order_by=username&order_by=created_at`, we will consider only the first `order_by` parameter, which is `username`. The `created_at` parameter will be ignored in this case.'
schema:
type: string
default: -created_at
required: false
responses:
'200':
$ref: '#/components/responses/User.List'
'400':
$ref: '#/components/responses/ClerkErrors'
'401':
$ref: '#/components/responses/AuthenticationInvalid'
'422':
$ref: '#/components/responses/UnprocessableEntity'
post:
operationId: CreateUser
x-speakeasy-group: users
x-speakeasy-name-override: create
summary: Create a New User
description: 'Creates a new user. Your user management settings determine how you should setup your user model.
Any email address and phone number created using this method will be marked as verified.
Note: If you are performing a migration, check out our guide on [zero downtime migrations](https://clerk.com/docs/deployments/migrate-overview).
The following rate limit rules apply to this endpoint: 1000 requests per 10 seconds for production instances and 100 requests per 10 seconds for development instances'
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
properties:
external_id:
type: string
description: 'The ID of the user as used in your external systems or your previous authentication solution.
Must be unique across your instance.'
nullable: true
first_name:
type: string
description: The first name to assign to the user
nullable: true
last_name:
type: string
description: The last name to assign to the user
nullable: true
locale:
type: string
description: The locale to assign to the user (e.g., "en-US", "fr-FR")
nullable: true
email_address:
type: array
items:
type: string
description: 'Email addresses to add to the user.
Must be unique across your instance.
The first email address will be set as the user''s primary email address.'
phone_number:
type: array
items:
type: string
description: 'Phone numbers to add to the user.
Must be unique across your instance.
The first phone number will be set as the user''s primary phone number.'
web3_wallet:
type: array
items:
type: string
description: 'Web3 wallets to add to the user.
Must be unique across your instance.
The first wallet will be set as the user''s primary wallet.'
username:
type: string
description: 'The username to give to the user.
It must be unique across your instance.'
nullable: true
password:
type: string
description: 'The plaintext password to give the user.
Must be at least 8 characters long, and cannot be in any list of hacked passwords.'
nullable: true
password_digest:
type: string
description: 'In case you already have the password digests and not the passwords, you can use them for the newly created user via this property.
The digests should be generated with one of the supported algorithms.
The hashing algorithm can be specified using the `password_hasher` property.'
nullable: true
password_hasher:
$ref: '#/components/schemas/PasswordHasher'
skip_password_checks:
type: boolean
description: 'When set to `true` all password checks are skipped.
It is recommended to use this method only when migrating plaintext passwords to Clerk.
Upon migration the user base should be prompted to pick stronger password.'
nullable: true
skip_password_requirement:
type: boolean
description: 'When set to `true`, `password` is not required anymore when creating the user and can be omitted.
This is useful when you are trying to create a user that doesn''t have a password, in an instance that is using passwords.
Please note that you cannot use this flag if password is the only way for a user to sign into your instance.'
nullable: true
totp_secret:
type: string
description: 'In case TOTP is configured on the instance, you can provide the secret to enable it on the newly created user without the need to reset it.
Please note that currently the supported options are:
* Period: 30 seconds
* Code length: 6 digits
* Algorithm: SHA1'
nullable: true
backup_codes:
type: array
items:
type: string
description: 'If Backup Codes are configured on the instance, you can provide them to enable it on the newly created user without the need to reset them.
You must provide the backup codes in plain format or the corresponding bcrypt digest.'
public_metadata:
type: object
description: Metadata saved on the user, that is visible to both your Frontend and Backend APIs
additionalProperties: true
private_metadata:
type: object
description: Metadata saved on the user, that is only visible to your Backend API
additionalProperties: true
unsafe_metadata:
type: object
description: 'Metadata saved on the user, that can be updated from both the Frontend and Backend APIs.
Note: Since this data can be modified from the frontend, it is not guaranteed to be safe.'
additionalProperties: true
delete_self_enabled:
type: boolean
description: 'If enabled, user can delete themselves via FAPI.
'
nullable: true
legal_accepted_at:
type: string
description: A custom timestamp denoting _when_ the user accepted legal requirements, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`).
nullable: true
skip_legal_checks:
type: boolean
description: 'When set to `true` all legal checks are skipped.
It is not recommended to skip legal checks unless you are migrating a user to Clerk.'
nullable: true
skip_user_requirement:
type: boolean
description: 'When set to `true`, identification types are not enforced.
At least one identification type must be enabled and provided on your instance (email, phone, web3 wallet, or username).
Users created without required identification types cannot use those authentication strategies
It is not recommended to use this flag unless you need to allow Clerk UI components to prompt for required fields while BAPI creates users with minimal data, or for migration a user to Clerk.'
nullable: true
create_organization_enabled:
type: boolean
description: 'If enabled, user can create organizations via FAPI.
'
nullable: true
create_organizations_limit:
type: integer
description: 'The maximum number of organizations the user can create. 0 means unlimited.
'
nullable: true
created_at:
type: string
description: A custom date/time denoting _when_ the user signed up to the application, specified in RFC3339 format (e.g. `2012-10-20T07:15:20.902Z`).
nullable: true
bypass_client_trust:
type: boolean
description: When set to `true`, the user will bypass client trust checks during sign-in.
nullable: true
responses:
'200':
$ref: '#/components/responses/User'
'400':
$ref: '#/components/responses/ClerkErrors'
'401':
$ref: '#/components/responses/AuthenticationInvalid'
'403':
$ref: '#/components/responses/AuthenticationInvalid'
'422':
$ref: '#/components/responses/UnprocessableEntity'
/users/count:
get:
operationId: GetUsersCount
x-speakeasy-group: users
x-speakeasy-name-override: count
summary: Count Users
description: Returns a total count of all users that match the given filtering criteria.
tags:
- Users
parameters:
- name: email_address
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the specified email addresses.
Accepts up to 100 email addresses.
Any email addresses not found are ignored.'
required: false
- name: phone_number
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the specified phone numbers.
Accepts up to 100 phone numbers.
Any phone numbers not found are ignored.'
required: false
- name: external_id
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the specified external IDs.
Accepts up to 100 external IDs.
Any external IDs not found are ignored.'
required: false
- name: username
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the specified usernames.
Accepts up to 100 usernames.
Any usernames not found are ignored.'
required: false
- name: web3_wallet
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the specified web3 wallet addresses.
Accepts up to 100 web3 wallet addresses.
Any web3 wallet addresses not found are ignored.'
required: false
- name: user_id
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the user IDs specified.
Accepts up to 100 user IDs.
Any user IDs not found are ignored.'
required: false
- name: organization_id
in: query
schema:
type: array
items:
type: string
description: 'Returns users that have memberships to the given organizations. For each organization ID, the `+` and `-`
can be prepended to the ID, which denote whether the respective organization should be included or
excluded from the result set. Accepts up to 100 organization IDs.'
required: false
- name: query
in: query
description: 'Counts users that match the given query.
For possible matches, we check the email addresses, phone numbers, usernames, web3 wallets, user IDs, first and last names.
The query value doesn''t need to match the exact value you are looking for, it is capable of partial matches as well.'
schema:
type: string
required: false
- name: email_address_query
in: query
description: 'Counts users with emails that match the given query, via case-insensitive partial match.
For example, `email_address_query=ello` will match a user with the email `HELLO@example.com`,
and will be included in the resulting count.'
schema:
type: string
required: false
- name: phone_number_query
in: query
description: 'Counts users with phone numbers that match the given query, via case-insensitive partial match.
For example, `phone_number_query=555` will match a user with the phone number `+1555xxxxxxx`,
and will be included in the resulting count.'
schema:
type: string
required: false
- name: username_query
in: query
description: 'Counts users with usernames that match the given query, via case-insensitive partial match.
For example, `username_query=CoolUser` will match a user with the username `SomeCoolUser`,
and will be included in the resulting count.'
schema:
type: string
- name: name_query
in: query
description: Returns users with names that match the given query, via case-insensitive partial match.
schema:
type: string
- name: banned
in: query
required: false
description: Counts users which are either banned (`banned=true`) or not banned (`banned=false`).
schema:
type: boolean
- name: last_active_at_before
in: query
description: 'Returns users whose last session activity was before the given date (with millisecond precision).
Example: use 1700690400000 to retrieve users whose last session activity was before 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: last_active_at_after
in: query
description: 'Returns users whose last session activity was after the given date (with millisecond precision).
Example: use 1700690400000 to retrieve users whose last session activity was after 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: last_active_at_since
in: query
deprecated: true
description: 'Returns users that had session activity since the given date.
Example: use 1700690400000 to retrieve users that had session activity from 2023-11-23 until the current day.
Deprecated in favor of `last_active_at_after`.'
example: 1700690400000
schema:
type: integer
- name: created_at_before
in: query
description: 'Returns users who have been created before the given date (with millisecond precision).
Example: use 1730160000000 to retrieve users who have been created before 2024-10-29.'
example: 1730160000000
schema:
type: integer
- name: created_at_after
in: query
description: 'Returns users who have been created after the given date (with millisecond precision).
Example: use 1730160000000 to retrieve users who have been created after 2024-10-29.'
example: 1730160000000
schema:
type: integer
- name: last_sign_in_at_before
in: query
description: 'Counts users whose last sign-in was before the given date (with millisecond precision).
Example: use 1700690400000 to count users whose last sign-in was before 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: last_sign_in_at_after
in: query
description: 'Counts users whose last sign-in was after the given date (with millisecond precision).
Example: use 1700690400000 to count users whose last sign-in was after 2023-11-23.'
example: 1700690400000
schema:
type: integer
- name: provider
in: query
schema:
type: string
description: 'Counts users with external accounts for the specified OAuth provider.
Must be used in combination with the `provider_user_id` parameter.
For example, use `provider=oauth_google&provider_user_id=12345` to count users with Google provider user ID 12345.
Accepts up to 100 providers.'
required: false
- name: provider_user_id
in: query
schema:
type: array
items:
type: string
description: 'Counts users with the specified provider user IDs for a specific provider.
Must be used in combination with the `provider` parameter.
For example, use `provider=oauth_google&provider_user_id=12345` to count users with Google provider user ID 12345.
Accepts up to 100 provider user IDs.
Any provider user IDs not found are ignored.'
required: false
responses:
'200':
$ref: '#/components/responses/User.Count'
'422':
$ref: '#/components/responses/UnprocessableEntity'
/users/{user_id}:
get:
operationId: GetUser
x-speakeasy-group: users
x-speakeasy-name-override: get
summary: Retrieve a User
description: Retrieve the details of a user
tags:
- Users
parameters:
- name: user_id
in: path
description: The ID of the user to retrieve
required: true
schema:
type: string
responses:
'200':
$ref: '#/components/responses/User'
'400':
$ref: '#/components/responses/ClerkErrors'
'401':
$ref: '#/components/responses/AuthenticationInvalid'
'404':
$ref: '#/components/responses/ResourceNotFound'
patch:
operationId: UpdateUser
x-speakeasy-group: users
x-speakeasy-name-override: update
summary: Update a User
description: 'Update a user''s attributes.
You can set the user''s primary contact identifiers (email address and phone numbers) by updating the `primary_email_address_id` and `primary_phone_number_id` attributes respectively.
Both IDs should correspond to verified identifications that belong to the user.
You can remove a user''s username by setting the username attribute to null or the blank string "".
This is a destructive action; the identification will be deleted forever.
Usernames can be removed only if they are optional in your instance settings and there''s at least one other identifier which can be used for authentication.
This endpoint allows changing a user''s password. When passing the `password` parameter directly you have two further options.
You can ignore the password policy checks for your instance by setting the `skip_password_checks` parameter to `true`.
You can also choose to sign the user out of all their active sessions on any device once the password is updated. Just set `sign_out_of_other_sessions` to `true`.'
tags:
- Users
parameters:
- name: user_id
in: path
description: The ID of the user to update
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
properties:
external_id:
type: string
description: 'The ID of the user as used in your external systems or your previous authentication solution.
Must be unique across your instance.'
nullable: true
first_name:
type: string
description: The first name to assign to the user
nullable: true
last_name:
type: string
description: The last name to assign to the user
nullable: true
locale:
type: string
description: The locale to assign to the user (e.g., "en-US", "fr-FR")
nullable: true
primary_email_address_id:
type: string
description: 'The ID of the email address to set as primary.
It must be verified, and present on the current user.'
nullable: true
notify_primary_email_address_changed:
type: boolean
description: 'If set to `true`, the user will be notified that their primary email address has changed.
By default, no notification is sent.'
nullable: true
default: false
primary_phone_number_id:
type: string
description: 'The ID of the phone number to set as primary.
It must be verified, and present on the current user.'
nullable: true
primary_web3_wallet_id:
type: string
description: 'The ID of the web3 wallets to set as primary.
It must be verified, and present on the current user.'
nullable: true
username:
type: string
description: 'The username to give to the user.
It must be unique across your instance.'
nullable: true
profile_image_id:
# --- truncated at 32 KB (144 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/clerk-com/refs/heads/main/openapi/clerk-com-users-api-openapi.yml