Skip to main content
POST
/
users
Create User
curl --request POST \
  --url https://api.example.com/users \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "<string>",
  "email": "<string>",
  "password": "<string>",
  "role": {}
}
'
{
  "201": {},
  "400": {},
  "id": 123,
  "name": "<string>",
  "email": "<string>",
  "role": {},
  "createdAt": {},
  "_links": {
    "self": {
      "href": "<string>"
    }
  }
}

Description

Create a new user in the system. The password will be automatically encrypted using PasswordEncoder before storage.
Passwords are automatically hashed using Spring Security’s PasswordEncoder before being stored in the database. Never store plain-text passwords.
The createdAt timestamp is automatically set to the current time and does not need to be provided in the request.

Request Body

Provide a JSON object with the user details.
name
string
required
Full name of the user
email
string
required
Email address of the user. Must be unique in the system.
password
string
required
Plain-text password for the user. Will be encrypted before storage. Cannot be empty or whitespace-only.
role
enum
required
User role in the system. Possible values: CUSTOMER, ADMIN

Response

Returns the created user object wrapped in EntityModel with HATEOAS links. The response includes a Location header with the URI of the newly created resource.
id
Long
required
Unique identifier for the newly created user
name
string
required
Full name of the user
email
string
required
Email address of the user
role
enum
required
User role in the system. Possible values: CUSTOMER, ADMIN
createdAt
LocalDateTime
required
Timestamp when the user was created (ISO 8601 format)
HATEOAS links for the user resource
self
object
Link to this specific user
href
string
URL to the user resource

Status Codes

201
Created
User successfully created. The Location header contains the URI of the new user.
400
Bad Request
Invalid request. This occurs when:
  • Password is null, empty, or contains only whitespace
  • Email already exists in the system

Validation Rules

Email Uniqueness: The system checks if the email already exists using userRepository.existsByEmail(). Duplicate emails will result in a 400 Bad Request.
Password Validation: Password cannot be null, empty, or contain only whitespace characters. The validation occurs before encryption.

Security

All passwords are encrypted using Spring Security’s PasswordEncoder before being persisted to the database. The plain-text password is never stored.
The password field is never included in response objects. The API returns a UserView object which excludes the password field.

Example Request

cURL
curl -X POST http://localhost:8080/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Alice Johnson",
    "email": "[email protected]",
    "password": "SecurePassword123!",
    "role": "CUSTOMER"
  }'

Example Response

Success (201 Created)

Headers:
Location: http://localhost:8080/users/3
Content-Type: application/json
Body:
{
  "id": 3,
  "name": "Alice Johnson",
  "email": "[email protected]",
  "role": "CUSTOMER",
  "createdAt": "2026-03-03T09:45:22",
  "_links": {
    "self": {
      "href": "http://localhost:8080/users/3"
    }
  }
}

Error - Empty Password (400 Bad Request)

cURL
curl -X POST http://localhost:8080/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Bob Smith",
    "email": "[email protected]",
    "password": "   ",
    "role": "CUSTOMER"
  }'
Response:
400 Bad Request

Error - Duplicate Email (400 Bad Request)

cURL
curl -X POST http://localhost:8080/users \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Another User",
    "email": "[email protected]",
    "password": "AnotherPassword123!",
    "role": "ADMIN"
  }'
Response:
400 Bad Request

Implementation Details

The endpoint performs the following operations (from UserController.java:44-65):
  1. Validates that the password is not null or empty
  2. Checks if the email already exists in the database
  3. Encrypts the password using PasswordEncoder.encode()
  4. Sets the createdAt timestamp to the current time
  5. Saves the user to the database
  6. Returns a 201 Created response with the Location header pointing to the new resource

Build docs developers (and LLMs) love