Skip to main content

User CRUD Operations

Create User

Create a new user in the current tenant.

Endpoint

POST /users

Request

{
"email": "jane.smith@example.com",
"password": "SecureP@ss123",
"firstName": "Jane",
"lastName": "Smith"
}

Response (201 Created)

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "jane.smith@example.com",
"firstName": "Jane",
"lastName": "Smith",
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "ACTIVE",
"lastLoginAt": null,
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}

Error: Duplicate Email

{
"type": "https://api.cortex.purplelab.ai/errors/conflict",
"title": "Conflict",
"status": 409,
"detail": "A user with this email already exists"
}

List Users

List users in the current tenant with pagination and filtering.

Endpoint

GET /users

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20, max: 100)
statusstringFilter by status (ACTIVE, SUSPENDED, INACTIVE)
searchstringSearch by email, first name, or last name
organizationIdUUIDFilter by organization membership

Response (200 OK)

{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "jane.smith@example.com",
"firstName": "Jane",
"lastName": "Smith",
"status": "ACTIVE",
"lastLoginAt": "2024-01-15T09:00:00.000Z"
},
{
"id": "661f9511-f30c-52e5-b827-ff3366551111",
"email": "john.doe@example.com",
"firstName": "John",
"lastName": "Doe",
"status": "ACTIVE",
"lastLoginAt": "2024-01-14T14:30:00.000Z"
}
],
"pagination": {
"total": 45,
"page": 1,
"limit": 20,
"totalPages": 3
}
}

Get User

Retrieve a specific user by ID.

Endpoint

GET /users/:id

Response (200 OK)

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "jane.smith@example.com",
"firstName": "Jane",
"lastName": "Smith",
"tenantId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "ACTIVE",
"lastLoginAt": "2024-01-15T09:00:00.000Z",
"createdAt": "2024-01-01T10:00:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z"
}

Update User

Update user properties.

Endpoint

PATCH /users/:id

Request

{
"firstName": "Janet",
"lastName": "Smith-Johnson"
}

Updatable Fields

FieldTypeDescription
firstNamestringFirst name
lastNamestringLast name
emailstringEmail (requires uniqueness check)
statusstringUser status

Response (200 OK)

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "jane.smith@example.com",
"firstName": "Janet",
"lastName": "Smith-Johnson",
"status": "ACTIVE",
"updatedAt": "2024-01-15T12:00:00.000Z"
}

Delete User

Soft-delete a user (sets status to INACTIVE).

Endpoint

DELETE /users/:id

Response (204 No Content)

No response body on success.

caution

Deleting a user:

  • Sets their status to INACTIVE
  • Terminates all active sessions
  • Revokes all role assignments
  • The user cannot log in

Code Examples

TypeScript

interface User {
id: string;
email: string;
firstName: string;
lastName: string;
tenantId: string;
status: 'ACTIVE' | 'SUSPENDED' | 'INACTIVE';
lastLoginAt: string | null;
createdAt: string;
updatedAt: string;
}

interface CreateUserDto {
email: string;
password: string;
firstName: string;
lastName: string;
}

class UserClient {
constructor(private accessToken: string) {}

private headers() {
return {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.accessToken}`,
};
}

async create(data: CreateUserDto): Promise<User> {
const response = await fetch('http://localhost:8091/users', {
method: 'POST',
headers: this.headers(),
body: JSON.stringify(data),
});
return response.json();
}

async list(params?: { page?: number; status?: string }): Promise<{
data: User[];
pagination: any;
}> {
const url = new URL('http://localhost:8091/users');
if (params?.page) url.searchParams.set('page', String(params.page));
if (params?.status) url.searchParams.set('status', params.status);

const response = await fetch(url, { headers: this.headers() });
return response.json();
}

async get(id: string): Promise<User> {
const response = await fetch(`http://localhost:8091/users/${id}`, {
headers: this.headers(),
});
return response.json();
}

async update(id: string, data: Partial<User>): Promise<User> {
const response = await fetch(`http://localhost:8091/users/${id}`, {
method: 'PATCH',
headers: this.headers(),
body: JSON.stringify(data),
});
return response.json();
}

async delete(id: string): Promise<void> {
await fetch(`http://localhost:8091/users/${id}`, {
method: 'DELETE',
headers: this.headers(),
});
}
}

cURL

# Create user
curl -X POST http://localhost:8091/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{
"email": "jane.smith@example.com",
"password": "SecureP@ss123",
"firstName": "Jane",
"lastName": "Smith"
}'

# List users
curl "http://localhost:8091/users?page=1&limit=20" \
-H "Authorization: Bearer <access-token>"

# Get user
curl http://localhost:8091/users/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer <access-token>"

# Update user
curl -X PATCH http://localhost:8091/users/550e8400-e29b-41d4-a716-446655440000 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access-token>" \
-d '{"firstName": "Janet"}'

# Delete user
curl -X DELETE http://localhost:8091/users/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer <access-token>"