User Registration
Create new user accounts within a tenant.
Endpoint
POST /auth/register
Request Body
{
"email": "john.doe@acme.com",
"password": "SecureP@ss123",
"firstName": "John",
"lastName": "Doe",
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}
Fields
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Valid email address (unique per tenant) |
password | string | Yes | Must meet password policy |
firstName | string | Yes | User's first name |
lastName | string | Yes | User's last name |
tenantId | UUID | Yes | Target tenant ID |
Response (201 Created)
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john.doe@acme.com",
"firstName": "John",
"lastName": "Doe",
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "ACTIVE",
"createdAt": "2024-01-15T10:30:00.000Z"
}
}
Error Responses
400 Bad Request — Validation Error
{
"type": "https://api.cortex.purplelab.ai/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "password must contain at least one uppercase letter",
"instance": "/auth/register"
}
409 Conflict — Email Already Exists
{
"type": "https://api.cortex.purplelab.ai/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "A user with this email already exists in this tenant",
"instance": "/auth/register"
}
404 Not Found — Invalid Tenant
{
"type": "https://api.cortex.purplelab.ai/errors/not-found",
"title": "Not Found",
"status": 404,
"detail": "Tenant not found",
"instance": "/auth/register"
}
Password Requirements
| Requirement | Description |
|---|---|
| Minimum length | 8 characters |
| Uppercase | At least 1 character (A-Z) |
| Lowercase | At least 1 character (a-z) |
| Number | At least 1 digit (0-9) |
| Special character | At least 1 of: !@#$%^&*()_+-=[]{} |
Code Examples
TypeScript
interface RegisterRequest {
email: string;
password: string;
firstName: string;
lastName: string;
tenantId: string;
}
async function registerUser(data: RegisterRequest) {
const response = await fetch('http://localhost:8091/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail);
}
return response.json();
}
// Usage
const result = await registerUser({
email: 'john.doe@acme.com',
password: 'SecureP@ss123',
firstName: 'John',
lastName: 'Doe',
tenantId: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
});
console.log('User ID:', result.user.id);
console.log('Access Token:', result.accessToken);
cURL
curl -X POST http://localhost:8091/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@acme.com",
"password": "SecureP@ss123",
"firstName": "John",
"lastName": "Doe",
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}'
Notes
- Newly registered users have
ACTIVEstatus by default - Email addresses are case-insensitive and stored in lowercase
- The same email can exist in different tenants (tenant-scoped uniqueness)
- Registration automatically logs in the user (returns tokens)