# Kagome Auth API - Integration Guide for LLMs ## Overview Kagome Auth API is a production-ready authentication and user management service built with Bun and Hono. It uses Better Auth with Drizzle ORM for secure, production-ready authentication with PostgreSQL, providing automatic session management, user registration, login, profile management, and comprehensive security features. ## Base URL - Production: `https://kagome-api.thamelthreads.com` - Development: `http://localhost:3000` ## API Status ✅ **FULLY OPERATIONAL** - All endpoints tested and working - User registration and authentication ✅ - Profile management with image upload ✅ - Session management ✅ - Rate limiting and security ✅ - S3 file storage integration ✅ ## API Design Standards - **Versioning**: All endpoints prefixed with `/v1/` - **Standard Responses**: Consistent `{ success: true, data: {...} }` or `{ success: false, error: {...} }` format - **HTTP Status Codes**: Proper 200, 201, 400, 401, 403, 404, 422, 500 codes - **Pagination**: `?limit=50&offset=0&sort=created_at&order=desc` - **Filtering**: Query parameters for filtering results ## API Endpoints ### Home Page **GET** `/` - **Description**: Get the main home page with system status information - **Authentication**: None required - **Response**: HTML content with embedded status information and version badge ### Health Check **GET** `/v1/health` - **Description**: Check API health status - **Authentication**: None required - **Response**: ```json { "success": true, "data": { "status": "ok" | "degraded", "db": { "ok": boolean, "error"?: string } } } ``` ### User Registration **POST** `/api/auth/sign-up/email` - **Description**: Register a new user account with email and password - **Authentication**: None required - **Request Body**: ```json { "email": "user@example.com", "password": "password123", "name": "John Doe" } ``` - **Validation**: - Email must be valid email format - Password must be at least 8 characters - Name is required - **Response** (200 OK): ```json { "user": { "id": "user_1234567890abcdef1234567890abcdef", "name": "John Doe", "email": "user@example.com", "emailVerified": false, "image": null, "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" }, "session": { "id": "session_123456789", "expiresAt": "2024-01-15T11:30:00.000Z", "token": "session_token_here", "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z", "ipAddress": "192.168.1.100", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "userId": "user_1234567890abcdef1234567890abcdef" } } ``` ### User Registration **POST** `/api/auth/sign-up/email` - **Description**: Register a new user account with email and password - **Authentication**: None required - **Request Body**: ```json { "email": "user@example.com", "password": "password123", "name": "John Doe" } ``` - **Validation**: - Email must be valid email format - Password must be at least 8 characters - Name is required - **Response** (200 OK): ```json { "user": { "id": "user_1234567890abcdef1234567890abcdef", "name": "John Doe", "email": "user@example.com", "emailVerified": false, "image": null, "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" }, "session": { "id": "session_123456789", "expiresAt": "2024-01-15T11:30:00.000Z", "token": "session_token_here", "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z", "ipAddress": "192.168.1.100", "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "userId": "user_1234567890abcdef1234567890abcdef" } } ``` ### User Login **POST** `/api/auth/sign-in/email` - **Description**: Authenticate user with email and password - **Authentication**: None required - **Request Body**: ```json { "email": "user@example.com", "password": "password123" } ``` - **Response** (200 OK): ```json { "user": { "id": "user_123456789", "name": "John Doe", "email": "user@example.com", "emailVerified": false, "image": null, "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" }, "session": { "id": "session_123456789", "expiresAt": "2024-01-15T11:30:00.000Z", "token": "session_token_here", "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z", "ipAddress": "192.168.1.100", "userAgent": "Mozilla/5.0...", "userId": "user_123456789" } } ``` ### Get Current Session **GET** `/api/auth/get-session` - **Description**: Get current user session information - **Authentication**: Handled automatically by session cookie/token - **Response** (200 OK): ```json { "user": { "id": "user_123456789", "name": "John Doe", "email": "user@example.com", "emailVerified": false, "image": null, "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" }, "session": { "id": "session_123456789", "expiresAt": "2024-01-15T11:30:00.000Z", "token": "session_token_here", "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z", "ipAddress": "192.168.1.100", "userAgent": "Mozilla/5.0...", "userId": "user_123456789" } } ``` ### User Logout **POST** `/api/auth/sign-out` - **Description**: Sign out current user and destroy session - **Authentication**: Handled automatically by session - **Response** (200 OK): ```json { "success": true } ``` ### Request Password Reset **POST** `/api/auth/forgot-password` - **Description**: Send a password reset email to the user - **Authentication**: None required - **Request Body**: ```json { "email": "user@example.com" } ``` - **Response** (200 OK): ```json { "success": true, "message": "Password reset email sent" } ``` ### Reset Password **POST** `/api/auth/reset-password` - **Description**: Reset user password using reset token - **Authentication**: None required - **Request Body**: ```json { "token": "reset_token_123456789", "password": "newpassword123" } ``` - **Response** (200 OK): ```json { "success": true, "message": "Password reset successfully" } ``` ### Update User Profile **PATCH** `/v1/user/update` - **Description**: Partially update current user's profile information. All fields are optional - only provided fields will be updated. Image can be either a file upload (stored in S3) or a URL string. - **Authentication**: Required (session-based) - **Request Body** (multipart/form-data): ```json { "name": "John Doe", "email": "user@example.com", "image": "File upload OR URL string (optional)" } ``` - **Validation**: - All fields are optional - Email must be valid email format if provided - Image can be either a file upload (stored in S3) or a valid URL string - File uploads: JPEG, PNG, WebP, GIF (max 5MB) - S3 storage with presigned URLs (7-day expiration) - **Response** (200 OK): ```json { "success": true, "data": { "id": "user_123456789", "name": "John Doe", "email": "user@example.com", "emailVerified": false, "image": "https://storage.example.com/avatars/user_123456789.png", "createdAt": "2024-01-15T10:30:00.000Z", "updatedAt": "2024-01-15T10:30:00.000Z" } } ``` - **Error Responses**: - 401 Unauthorized: User not authenticated - 400 Bad Request: Invalid input data - 500 Internal Server Error: Failed to update profile ### API Documentation **GET** `/docs` - **Description**: Interactive Swagger UI documentation - **Authentication**: None required **GET** `/swagger.json` - **Description**: OpenAPI specification in JSON format - **Authentication**: None required ## Authentication Flow ### 1. Registration/Login Flow 1. User registers via `POST /api/auth/sign-up/email` or logs in via `POST /api/auth/sign-in/email` 2. API creates a secure session and returns user + session data 3. Better Auth automatically manages session cookies/tokens 4. Client receives session confirmation with user data ### 2. Making Authenticated Requests 1. Better Auth handles authentication automatically via session cookies/tokens 2. No manual token management required 3. Sessions are automatically refreshed by Better Auth 4. Sessions expire after configurable time (default: 30 days) ### 3. Session Management 1. Better Auth automatically handles session validation 2. Sessions are securely stored and validated on each request 3. No manual refresh tokens needed - Better Auth handles renewal 4. Session data includes IP address and user agent tracking ## Better Auth Session Details ### Session Token - **Purpose**: Authenticate and maintain user sessions - **Expiration**: 30 days (configurable) - **Storage**: Secure HTTP-only cookies or local storage - **Security**: Encrypted and signed session data - **Tracking**: IP address and user agent logging for security ### Automatic Features - **Rate Limiting**: 100 requests per minute per session - **Session Refresh**: Automatic renewal of expiring sessions - **Security Headers**: Comprehensive security middleware - **CORS Support**: Cross-origin request handling - **Error Handling**: Structured error responses ## Error Handling ### Common HTTP Status Codes - **200 OK**: Request successful - **201 Created**: User registered successfully - **400 Bad Request**: Invalid request data (validation errors) - **401 Unauthorized**: Invalid or expired token - **403 Forbidden**: Valid token but insufficient permissions - **404 Not Found**: Endpoint not found - **422 Unprocessable Entity**: Validation error with field details - **429 Too Many Requests**: Rate limit exceeded - **500 Internal Server Error**: Server error ### Error Response Codes - **VALIDATION_ERROR** (400/422): Input validation failed - **UNAUTHORIZED** (401): Authentication required - **FORBIDDEN** (403): Access denied - **NOT_FOUND** (404): Resource not found - **APP_ERROR** (4xx/5xx): Application-specific error - **INTERNAL_ERROR** (500): Server error - **RATE_LIMIT_EXCEEDED** (429): Rate limit exceeded ### Error Response Format ```json { "success": false, "error": { "code": "ERROR_CODE", "message": "Error message", "details"?: "Additional error details" } } ``` ### Validation Errors When request validation fails (422 Unprocessable Entity): ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "Invalid payload", "details": { "fieldErrors": { "email": ["Invalid email format"], "password": ["Must be at least 8 characters"] } } } } ``` ## Rate Limiting ### API Rate Limiting - **Window**: 15 minutes (900 seconds) - **Limit**: 100 requests per window per IP address - **Scope**: Per IP address (using x-forwarded-for, x-real-ip, cf-connecting-ip headers) - **Headers**: RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset - **Implementation**: Hono rate limiter middleware ### Rate Limit Handling When rate limit is exceeded (429 Too Many Requests): - API returns 429 status with error response - Headers indicate remaining requests and reset time - Automatic retry after window resets ## Security Features ### Better Auth Security - **Production-Ready**: Battle-tested authentication library - **Secure Sessions**: Encrypted session management - **Automatic Security**: No manual security implementation needed - **Industry Standards**: Follows security best practices ### Session Security - **IP Tracking**: Sessions track IP addresses for security monitoring - **User Agent Logging**: Records user agents for suspicious activity detection - **Secure Tokens**: Encrypted and signed session tokens - **Automatic Expiry**: Sessions expire securely after inactivity ### Password Security - **Secure Hashing**: Industry-standard password hashing - **Minimum Requirements**: Enforced password complexity - **No Plain Text**: Passwords never stored or returned in plain text ### Session Activity Tracking - **Automatic Logging**: All authentication activities logged - **IP & User Agent**: Comprehensive session tracking - **Security Monitoring**: Built-in suspicious activity detection - **Session Management**: Automatic session cleanup and validation ## Database Schema The database schema is managed using Better Auth with Drizzle ORM and TypeScript type safety: ### Better Auth Tables - **user**: User accounts with email, name, verification status - **session**: Active user sessions with IP and user agent tracking - **account**: OAuth provider accounts (extensible for social login) - **verification**: Email verification and password reset tokens ### Schema Features - **Type Safety**: Full TypeScript integration with Drizzle ORM - **Automatic Migrations**: drizzle-kit handles schema updates - **Security Tracking**: IP address and user agent logging - **Session Management**: Automatic session cleanup and validation - **Extensible**: Ready for OAuth providers and additional features ## Integration Examples ### JavaScript/TypeScript ```javascript // Register user const registerResponse = await fetch('https://kagome-api.thamelthreads.com/api/auth/sign-up', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'user@example.com', password: 'password123', name: 'John Doe' }) }); const registerData = await registerResponse.json(); // Better Auth automatically handles session management // No need to manually store tokens - sessions are handled via cookies/tokens const { user, session } = registerData; // Get current session (automatically authenticated) const sessionResponse = await fetch('https://kagome-api.thamelthreads.com/api/auth/session'); const sessionData = await sessionResponse.json(); // Session data includes user info and is automatically validated // Sign out const logoutResponse = await fetch('https://kagome-api.thamelthreads.com/api/auth/sign-out', { method: 'POST' }); // Sign in (alternative to register) const loginResponse = await fetch('https://kagome-api.thamelthreads.com/api/auth/sign-in', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'user@example.com', password: 'password123' }) }); const loginData = await loginResponse.json(); const { user: loggedInUser, session: loginSession } = loginData; // Update user profile (partial update with file upload) const formData = new FormData(); formData.append('name', 'John Updated'); formData.append('email', 'john.updated@example.com'); formData.append('image', fileInput.files[0]); // File upload const updateProfileResponse = await fetch('https://kagome-api.thamelthreads.com/v1/user/update', { method: 'PATCH', body: formData // No Content-Type header needed for FormData }); const updateData = await updateProfileResponse.json(); const { data: updatedUser } = updateData; // Example: Update only name const nameFormData = new FormData(); nameFormData.append('name', 'John Only Name Updated'); const updateNameResponse = await fetch('https://kagome-api.thamelthreads.com/v1/user/update', { method: 'PATCH', body: nameFormData }); // Example: Update only email const emailFormData = new FormData(); emailFormData.append('email', 'newemail@example.com'); const updateEmailResponse = await fetch('https://kagome-api.thamelthreads.com/v1/user/update', { method: 'PATCH', body: emailFormData }); // Example: Update with image URL string const urlFormData = new FormData(); urlFormData.append('name', 'John with URL Image'); urlFormData.append('image', 'https://example.com/avatar.jpg'); // URL string const updateWithUrlResponse = await fetch('https://kagome-api.thamelthreads.com/v1/user/update', { method: 'PATCH', body: urlFormData }); ``` ### Python ```python import requests # Register user register_data = { "email": "user@example.com", "password": "password123", "name": "John Doe" } response = requests.post( "https://kagome-api.thamelthreads.com/api/auth/sign-up", json=register_data ) result = response.json() # Better Auth automatically handles sessions # No need to manually manage tokens user = result["user"] session = result["session"] # Get current session (automatically authenticated via session cookies) session_response = requests.get( "https://kagome-api.thamelthreads.com/api/auth/session" ) session_result = session_response.json() current_user = session_result["user"] current_session = session_result["session"] # Sign out logout_response = requests.post( "https://kagome-api.thamelthreads.com/api/auth/sign-out" ) # Sign in (alternative to register) login_data = { "email": "user@example.com", "password": "password123" } login_response = requests.post( "https://kagome-api.thamelthreads.com/api/auth/sign-in", json=login_data ) login_result = login_response.json() logged_in_user = login_result["user"] login_session = login_result["session"] # Update user profile (partial update with file upload) files = {'image': open('avatar.jpg', 'rb')} data = { 'name': 'John Updated', 'email': 'john.updated@example.com' } update_response = requests.patch( "https://kagome-api.thamelthreads.com/v1/user/update", files=files, data=data ) update_result = update_response.json() updated_user = update_result["data"] # Example: Update with image URL string url_data = { 'name': 'John with URL Image', 'image': 'https://example.com/avatar.jpg' # URL string } url_update_response = requests.patch( "https://kagome-api.thamelthreads.com/v1/user/update", data=url_data ) ``` ### cURL ```bash # Register user curl -X POST https://kagome-api.thamelthreads.com/api/auth/sign-up/email \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"password123","name":"John Doe"}' # Sign in curl -X POST https://kagome-api.thamelthreads.com/api/auth/sign-in/email \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"password123"}' # Get current session (automatically uses session cookies) curl -X GET https://kagome-api.thamelthreads.com/api/auth/get-session # Sign out curl -X POST https://kagome-api.thamelthreads.com/api/auth/sign-out # Update user profile (partial update with file upload) curl -X PATCH https://kagome-api.thamelthreads.com/v1/user/update \ -F "name=John Updated" \ -F "email=john.updated@example.com" \ -F "image=@avatar.jpg" # Update user profile with image URL string curl -X PATCH https://kagome-api.thamelthreads.com/v1/user/update \ -F "name=John with URL Image" \ -F "image=https://example.com/avatar.jpg" ``` ## Technology Stack ### Core Technologies - **Runtime**: Bun - Fast JavaScript runtime - **Framework**: Hono - Lightweight web framework - **Language**: TypeScript - Type-safe JavaScript - **Database**: PostgreSQL - Reliable relational database - **ORM**: Drizzle ORM - Type-safe database operations ### Security & Authentication - **Better Auth**: Production-ready authentication library - **Session Management**: Secure session handling with encryption - **Rate Limiting**: Built-in rate limiting (100 requests/minute) - **Security Headers**: Comprehensive security middleware - **CORS**: Cross-origin resource sharing support ### Development Tools - **Drizzle Kit**: Database migration and management - **TypeScript**: Static type checking - **ESLint**: Code linting and formatting - **Swagger UI**: Interactive API documentation ## Environment Variables ### Required for Production - `DATABASE_URL`: PostgreSQL connection string - `PORT`: Server port (default: 3000) ### Better Auth Configuration Better Auth handles all authentication configuration automatically. No additional environment variables needed for authentication features. ## Best Practices ### Session Management 1. Better Auth automatically handles secure session management 2. Sessions are encrypted and stored securely 3. No manual token management required 4. Automatic session refresh and cleanup ### Error Handling 1. Always check response status codes 2. Implement retry logic for network errors 3. Handle rate limiting automatically (Better Auth built-in) 4. Provide user-friendly error messages ### Security 1. Use HTTPS in production 2. Validate all input data on client side 3. Better Auth provides comprehensive security automatically 4. Monitor session activity through Better Auth logging 5. IP address and user agent tracking for security monitoring 6. Automatic suspicious activity detection 7. Secure session encryption and validation ## Support For integration support or questions, refer to the interactive API documentation at `/docs` or the OpenAPI specification at `/swagger.json`.