# Register User & Tenant **POST /api/v1/register** Register a new user and create a new tenant (organization) in a single request. This is the primary onboarding endpoint that returns authentication tokens. **Authentication**: None required (public endpoint) **Headers**: - `Content-Type: application/json` **Request Body**: | Field | Type | Required | Description | |-------|------|----------|-------------| | email | string | Yes | User's email address | | password | string | Yes | User's password (min 8 characters) | | confirm_password | string | Yes | Password confirmation (must match password) | | first_name | string | Yes | User's first name | | last_name | string | Yes | User's last name | | tenant_name | string | Yes | Organization/tenant name (slug auto-generated from this) | | timezone | string | No | User's timezone (e.g., "America/New_York", defaults to "UTC" if not provided) | | agree_terms_of_service | boolean | Yes | Must be true - user agreement to Terms of Service | | agree_promotions | boolean | No | Optional - user agreement to receive promotional emails (default: false) | | agree_to_tracking_across_third_party_apps_and_services | boolean | No | Optional - user agreement to cross-platform tracking (default: false) | **Example Request (with timezone)**: ```bash curl -X POST http://localhost:8000/api/v1/register \ -H "Content-Type: application/json" \ -d '{ "email": "john@example.com", "password": "SecurePassword123!", "confirm_password": "SecurePassword123!", "first_name": "John", "last_name": "Doe", "tenant_name": "Acme Corporation", "timezone": "America/New_York", "agree_terms_of_service": true, "agree_promotions": false, "agree_to_tracking_across_third_party_apps_and_services": false }' ``` **Example Request (without timezone - defaults to UTC)**: ```bash curl -X POST http://localhost:8000/api/v1/register \ -H "Content-Type: application/json" \ -d '{ "email": "jane@example.com", "password": "SecurePassword456!", "confirm_password": "SecurePassword456!", "first_name": "Jane", "last_name": "Smith", "tenant_name": "Beta Inc", "agree_terms_of_service": true }' ``` **Example Response** (201 Created): ```json { "user_id": "550e8400-e29b-41d4-a716-446655440000", "user_email": "john@example.com", "user_name": "John Doe", "user_role": "manager", "tenant_id": "650e8400-e29b-41d4-a716-446655440000", "tenant_name": "Acme Corporation", "tenant_slug": "acme-corp", "session_id": "750e8400-e29b-41d4-a716-446655440000", "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "access_expiry": "2024-10-24T12:00:00Z", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_expiry": "2024-11-24T00:00:00Z", "created_at": "2024-10-24T00:00:00Z" } ``` **Error Responses**: This endpoint returns errors in **RFC 9457 (Problem Details for HTTP APIs)** format. **Validation Error Response** (400 Bad Request): ```json { "type": "about:blank", "title": "Validation Error", "status": 400, "detail": "One or more validation errors occurred", "errors": { "email": ["Invalid email format"], "password": ["Field is required", "Password must be at least 8 characters"], "confirm_password": ["Field is required", "Passwords do not match"], "first_name": ["Field is required"], "last_name": ["Field is required"], "tenant_name": ["Field is required"], "agree_terms_of_service": ["Must agree to terms of service"] } } ``` **Content-Type**: `application/problem+json` **Common Validation Error Messages**: | Field | Error Messages | |-------|---------------| | email | "Invalid email format", "Field is required" | | password | "Field is required", "Password must be at least 8 characters", "Password must contain at least one uppercase letter (A-Z)", "Password must contain at least one lowercase letter (a-z)", "Password must contain at least one number (0-9)", "Password must contain at least one special character" | | confirm_password | "Field is required", "Passwords do not match" | | first_name | "Field is required", "First_name must be between 1 and 100 characters" | | last_name | "Field is required", "Last_name must be between 1 and 100 characters" | | tenant_name | "Field is required", "Tenant_name must be between 1 and 100 characters" | | agree_terms_of_service | "Must agree to terms of service" | **Other Error Responses**: - `409 Conflict`: Email or tenant slug already exists ```json { "type": "about:blank", "title": "Conflict", "status": 409, "detail": "Registration failed. The provided information is already in use" } ``` - `500 Internal Server Error`: Server error ```json { "type": "about:blank", "title": "Internal Server Error", "status": 500, "detail": "Failed to register user" } ``` **Important Notes**: - `agree_terms_of_service` must be `true` or the request will fail with 400 Bad Request - `first_name` and `last_name` are required fields - `timezone` is optional and defaults to "UTC" if not provided - Password must be at least 8 characters long - **Tenant slug is automatically generated** from `tenant_name` (converted to lowercase, special chars replaced with hyphens) - The IP address of the request is automatically captured for audit trail purposes - User role for registration is always "manager" (tenant creator)