Skip to main content

Users & Permissions REST API

The Users & Permissions plugin exposes a set of REST API endpoints for authentication, user management, and role/permission management. These endpoints are separate from the standard content-type CRUD endpoints and have their own response shapes. For a general overview of the plugin's features and configuration, see the Users & Permissions introduction.

All endpoints use the /api prefix. For example, if your Strapi server runs at http://localhost:1337, the login endpoint is http://localhost:1337/api/auth/local.

Authentication

Authentication endpoints handle login, registration, and password management. Most of these endpoints are public by default and do not require a Bearer token.

Login

POST /api/auth/local

Authenticates a user with their identifier (email or username) and password, returning a JWT and the user object.

Request body:

{
"identifier": "user@example.com",
"password": "yourPassword"
}

Example request:

curl -X POST http://localhost:1337/api/auth/local \
-H "Content-Type: application/json" \
-d '{"identifier": "user@example.com", "password": "yourPassword"}'

Example response (200):

{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"documentId": "x74detpqybxw0bn6ormua5g2",
"username": "testuser1",
"email": "user@example.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"createdAt": "2024-03-15T10:00:00.000Z",
"updatedAt": "2024-03-15T10:00:00.000Z",
"publishedAt": "2024-03-15T10:00:00.000Z"
}
}

Possible errors:

StatusMessageCause
400"Invalid identifier or password"Wrong credentials
400"Your account email is not confirmed"Email confirmation required but not completed
400"Your account has been blocked by an administrator"Account blocked

This endpoint is rate limited (default: 10 requests per 60 seconds).

Register

POST /api/auth/local/register

Creates a new user account and returns a JWT along with the user object.

Request body:

{
"username": "newuser",
"email": "newuser@example.com",
"password": "Password123!"
}

Example request:

curl -X POST http://localhost:1337/api/auth/local/register \
-H "Content-Type: application/json" \
-d '{"username": "newuser", "email": "newuser@example.com", "password": "Password123!"}'

Example response (200):

{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 2,
"documentId": "xjpaytstw1gm7wdfoc6c2k13",
"username": "newuser",
"email": "newuser@example.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"createdAt": "2024-03-15T10:00:00.000Z",
"updatedAt": "2024-03-15T10:00:00.000Z",
"publishedAt": "2024-03-15T10:00:00.000Z"
}
}
Note

Only username, email, and password are accepted in the request body by default. To allow additional fields (e.g., a fullName field you added to the User content-type), you must explicitly list them in the register.allowedFields configuration. See Registration configuration for details.

When email confirmation is enabled, the response contains only the user object without a JWT -- the user must confirm their email before they can log in.

The newly registered user is assigned the default role (typically "Authenticated").

Possible errors:

StatusMessageCause
400"Email or Username are already taken"Duplicate email or username
400"Invalid parameters: fieldName"Extra fields not listed in allowedFields
400"Register action is currently disabled"Registration disabled in admin settings

This endpoint is rate limited.

Forgot password

POST /api/auth/forgot-password

Sends a password reset email to the specified address. Requires an email provider to be configured.

Request body:

{
"email": "user@example.com"
}

Example request:

curl -X POST http://localhost:1337/api/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'

Example response (200):

{
"ok": true
}
Note

This endpoint always returns { "ok": true } regardless of whether the email address exists in the system. This is intentional to prevent user enumeration attacks.

This endpoint is rate limited.

Reset password

POST /api/auth/reset-password

Resets a user's password using a token received by email. All 3 fields are required.

Request body:

{
"code": "resetTokenFromEmail",
"password": "NewPassword123!",
"passwordConfirmation": "NewPassword123!"
}

Example request:

curl -X POST http://localhost:1337/api/auth/reset-password \
-H "Content-Type: application/json" \
-d '{"code": "resetTokenFromEmail", "password": "NewPassword123!", "passwordConfirmation": "NewPassword123!"}'

Example response (200): Same shape as the login response (jwt + user).

Possible errors:

StatusMessageCause
400"passwordConfirmation is a required field"Missing passwordConfirmation
400"Incorrect code provided"Invalid or expired reset token

This endpoint is rate limited.

Change password

POST /api/auth/change-password

Changes the password for the currently authenticated user. Requires a valid Bearer token. All 3 fields are required.

Request body:

{
"currentPassword": "OldPassword123!",
"password": "NewPassword456!",
"passwordConfirmation": "NewPassword456!"
}

Example request:

curl -X POST http://localhost:1337/api/auth/change-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"currentPassword": "OldPassword123!", "password": "NewPassword456!", "passwordConfirmation": "NewPassword456!"}'

Example response (200): Same shape as the login response (jwt + user).

Possible errors:

StatusMessageCause
400"passwordConfirmation is a required field"Missing passwordConfirmation
400"The provided current password is invalid"Wrong current password
400New password must differ from current passwordSame password reused

This endpoint is rate limited.

Email confirmation

GET /api/auth/email-confirmation

Confirms a user's email address using a token from the confirmation email.

Query parameter: confirmation -- the token received in the confirmation email.

Example request:

curl -G http://localhost:1337/api/auth/email-confirmation \
--data-urlencode "confirmation=confirmationTokenHere"

After confirming the email, Strapi redirects the user to the URL configured in the admin panel under Settings > Users & Permissions > Advanced Settings > "Redirection url".

Send email confirmation

POST /api/auth/send-email-confirmation

Resends the confirmation email to a user who has not yet confirmed their email address.

Request body:

{
"email": "user@example.com"
}

Example request:

curl -X POST http://localhost:1337/api/auth/send-email-confirmation \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'

Example response (200):

{
"email": "user@example.com",
"sent": true
}

Possible errors:

StatusMessageCause
400"Already confirmed"User already confirmed their email
400"Your account has been blocked by an administrator"Account blocked

This endpoint is rate limited.

Provider authentication

GET /api/connect/:provider

Redirects the user to a third-party provider's login page (e.g., Google, GitHub, Discord). Replace :provider with the provider name. See Setting up providers for configuration instructions.

Provider callback

GET /api/auth/:provider/callback

Handles the OAuth callback after the user authenticates with a third-party provider. On success, returns the same response shape as login (jwt + user).

If the username derived from the provider profile already exists, a unique username is generated automatically to avoid conflicts.

Session management endpoints

When session management is enabled (jwtManagement: 'refresh' in the plugin configuration), these additional endpoints become available. They return 404 when the default legacy JWT mode is active.

Refresh token

POST /api/auth/refresh

Exchanges a refresh token for a new access token. The old refresh token is invalidated and a new one is returned (token rotation).

Request body:

{
"refreshToken": "yourRefreshToken"
}

Example request:

curl -X POST http://localhost:1337/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{"refreshToken": "yourRefreshToken"}'

Example response (200):

{
"jwt": "newAccessToken",
"refreshToken": "newRefreshToken"
}
Note

When httpOnly is enabled in the session configuration, the new refresh token is set as an HTTP-only cookie instead of being included in the response body. In that case, the response only contains { "jwt": "newAccessToken" }.

Logout

POST /api/auth/logout

Revokes all sessions for the authenticated user. Requires a valid Bearer token.

Example request:

curl -X POST http://localhost:1337/api/auth/logout \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200):

{
"ok": true
}

Users

User management endpoints handle CRUD operations on end-user records. Each endpoint requires the corresponding permission to be enabled for the user's role in the admin panel (Settings > Users & Permissions > Roles).

Response format

User endpoints return bare JSON objects (not wrapped in a data key), unlike standard Strapi content-type endpoints.

Get current user

GET /api/users/me

Returns the user associated with the provided JWT. Requires authentication.

Example request:

curl http://localhost:1337/api/users/me \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200):

{
"id": 1,
"documentId": "x74detpqybxw0bn6ormua5g2",
"username": "testuser1",
"email": "user@example.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"createdAt": "2024-03-15T10:00:00.000Z",
"updatedAt": "2024-03-15T10:00:00.000Z",
"publishedAt": "2024-03-15T10:00:00.000Z"
}

List users

GET /api/users

Returns a list of users. Supports filters, sort, and pagination query parameters.

Example request:

curl http://localhost:1337/api/users \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200): An array of user objects.

Get a user

GET /api/users/:id

Returns a single user by their integer id.

Example request:

curl http://localhost:1337/api/users/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200): A user object.

Count users

GET /api/users/count

Returns the total number of users. Supports the filters query parameter.

Example request:

curl http://localhost:1337/api/users/count \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200): A bare integer, for example:

42

Create a user

POST /api/users

Creates a new user. If role is omitted, the default role is assigned.

Request body:

{
"username": "newuser",
"email": "newuser@example.com",
"password": "Password123!",
"role": 1,
"confirmed": true
}

Example request:

curl -X POST http://localhost:1337/api/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"username": "newuser", "email": "newuser@example.com", "password": "Password123!", "role": 1, "confirmed": true}'

Example response (201): A user object with the populated role.

Update a user

PUT /api/users/:id

Updates an existing user. Only include the fields you want to change.

Example request:

curl -X PUT http://localhost:1337/api/users/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"username": "updateduser"}'

Example response (200): The updated user object.

Possible errors:

StatusMessageCause
404"User not found"No user with the given id
400"Username already taken" or "Email already taken"Duplicate value

Delete a user

DELETE /api/users/:id

Deletes a user by their integer id.

Example request:

curl -X DELETE http://localhost:1337/api/users/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200): The deleted user object.

Roles

Role endpoints manage end-user roles and their associated permissions. These endpoints use the /api/users-permissions/ prefix, not the standard /api/ prefix used by content-type endpoints.

List roles

GET /api/users-permissions/roles

Returns all available roles with user counts.

Example request:

curl http://localhost:1337/api/users-permissions/roles \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200):

{
"roles": [
{
"id": 1,
"name": "Authenticated",
"description": "Default role given to authenticated user.",
"type": "authenticated",
"nb_users": 2
},
{
"id": 2,
"name": "Public",
"description": "Default role given to unauthenticated user.",
"type": "public",
"nb_users": 0
}
]
}

Get a role

GET /api/users-permissions/roles/:id

Returns a single role by id, including its full permissions tree.

Example request:

curl http://localhost:1337/api/users-permissions/roles/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200): A role object with a nested permissions structure mapping plugins to controllers to actions.

Create a role

POST /api/users-permissions/roles

Creates a new role.

Request body:

{
"name": "Editor",
"description": "Can edit content",
"type": "editor"
}

Example request:

curl -X POST http://localhost:1337/api/users-permissions/roles \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"name": "Editor", "description": "Can edit content", "type": "editor"}'

Example response (200):

{
"ok": true
}

Update a role

PUT /api/users-permissions/roles/:id

Updates an existing role.

Example request:

curl -X PUT http://localhost:1337/api/users-permissions/roles/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"description": "Updated description"}'

Example response (200):

{
"ok": true
}

Delete a role

DELETE /api/users-permissions/roles/:id

Deletes a role by id. The Public role cannot be deleted. When a role is deleted, users assigned to it are reassigned to the Public role.

Example request:

curl -X DELETE http://localhost:1337/api/users-permissions/roles/3 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200):

{
"ok": true
}

Permissions

The permissions endpoint returns the complete permission tree, showing which actions are available across all plugins and content-types.

List permissions

GET /api/users-permissions/permissions

Returns a nested object mapping plugins to controllers to actions.

Example request:

curl http://localhost:1337/api/users-permissions/permissions \
-H "Authorization: Bearer YOUR_JWT_TOKEN"

Example response (200): A nested permissions object where keys are plugin names, sub-keys are controller names, and values contain the available actions with their enabled status and policy information.