Skip to main content

Endpoint

POST /recipe/signup
Creates a new user account with the provided email and password.

Request Body

email
string
required
The user’s email address. Will be normalized (lowercased and trimmed) before storage.
password
string
required
The user’s password. Cannot be an empty string.

Response

status
string
required
The status of the request. Either OK or EMAIL_ALREADY_EXISTS_ERROR.
user
object
The created user object. Only present when status is OK.
recipeUserId
string
The recipe-specific user ID. Only present in CDI >= 4.0.

Response Examples

{
  "status": "OK",
  "user": {
    "id": "fa7a0841-b533-4478-95533-0fde890c3d37",
    "email": "[email protected]",
    "timeJoined": 1234567890123,
    "tenantIds": ["public"]
  },
  "recipeUserId": "fa7a0841-b533-4478-95533-0fde890c3d37"
}

Implementation Details

Email Normalization

The email address is normalized using Utils.normaliseEmail() before being stored. This ensures:
  • Consistent email format across the system
  • Case-insensitive email matching
  • Proper duplicate detection

Password Validation

The API validates that:
  • Password is not an empty string
  • Additional password strength requirements should be enforced at the application level

Active User Tracking

Successful sign-up automatically updates the user’s last active timestamp using ActiveUsers.updateLastActive(). This is used for:
  • Usage analytics
  • License compliance
  • User activity monitoring

Multi-tenancy

This endpoint is tenant-specific:
  • The tenant identifier is extracted from the request
  • The API verifies that Email Password is enabled for the tenant
  • User data is stored in the tenant’s storage

User ID Mapping

The external user ID is set to null in the response by default. If you have user ID mapping configured, the mapping will be applied when retrieving the user in subsequent requests.

Error Cases

EMAIL_ALREADY_EXISTS_ERROR

Returned when a user with the provided email already exists in the tenant.
{
  "status": "EMAIL_ALREADY_EXISTS_ERROR"
}

Bad Request (400)

Returned when:
  • Password is an empty string
  • Required fields are missing
  • Invalid JSON in request body

Internal Server Error (500)

Returned when:
  • Database query fails
  • Tenant or app not found
  • Permission errors
  • Other internal errors

Code Reference

Implementation: SignUpAPI.java:56

Build docs developers (and LLMs) love