# LeoCRM API Overview > Summary of all API endpoints, grouped by domain. ## Base URL ``` http://localhost:8000/api/v1 ``` ## Authentication All endpoints (except `/health` and `/auth/login`) require a valid session cookie obtained via login. | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/auth/login` | POST | No | Login with email + password, returns session cookie | | `/api/v1/auth/register` | POST | No | Register first user (bootstrap) | | `/api/v1/auth/logout` | POST | Yes | Logout and destroy session | | `/api/v1/auth/me` | GET | Yes | Get current user profile | | `/api/v1/auth/refresh` | POST | Yes | Refresh session token | ## Health & Monitoring | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/health` | GET | No | Health check (DB, Redis, storage, worker) | | `/api/v1/metrics` | GET | Admin | Prometheus metrics (text/plain) | ## Contacts | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/contacts` | GET | Yes | List contacts (pagination, search, sort) — page_size max 100 | | `/api/v1/contacts` | POST | Yes | Create a contact (with optional company links) | | `/api/v1/contacts/export` | GET | Yes | Stream contacts as CSV (StreamingResponse) | | `/api/v1/contacts/{id}` | GET | Yes | Get a single contact with companies | | `/api/v1/contacts/{id}` | PUT | Yes | Update a contact | | `/api/v1/contacts/{id}` | DELETE | Yes | Delete a contact (soft or GDPR hard-delete) | ### Query Parameters (List) | Parameter | Type | Default | Constraints | |---|---|---|---| | `page` | int | 1 | ≥1 | | `page_size` | int | 20 | ≥1, ≤100 (max 100 enforced) | | `search` | string | _(none)_ | Searches first_name, last_name, email | | `sort_by` | string | last_name | Column name | | `sort_order` | string | asc | `asc` or `desc` | ## Companies | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/companies` | GET | Yes | List companies (pagination, FTS, industry filter) — page_size max 100 | | `/api/v1/companies` | POST | Yes | Create a company | | `/api/v1/companies/export` | GET | Yes | Stream companies as CSV or XLSX | | `/api/v1/companies/{id}` | GET | Yes | Get a single company with contacts | | `/api/v1/companies/{id}` | PUT | Yes | Update a company | | `/api/v1/companies/{id}` | DELETE | Yes | Soft-delete a company | | `/api/v1/companies/{id}/contacts/{cid}` | POST | Yes | Link a contact to a company (N:M) | | `/api/v1/companies/{id}/contacts/{cid}` | DELETE | Yes | Unlink a contact from a company | | `/api/v1/companies/{id}/emails` | GET | Yes | Get emails for a company | ## Users & Roles | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/users` | GET | Admin | List users | | `/api/v1/users` | POST | Admin | Create/invite a user | | `/api/v1/users/{id}` | GET | Yes | Get user details | | `/api/v1/users/{id}` | PATCH | Admin | Update user (activate/deactivate, role) | | `/api/v1/users/{id}` | DELETE | Admin | Delete a user | | `/api/v1/roles` | GET | Admin | List roles | | `/api/v1/roles` | POST | Admin | Create a custom role | | `/api/v1/roles/{id}` | PUT | Admin | Update a role | | `/api/v1/roles/{id}` | DELETE | Admin | Delete a custom role | ## Tenants | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/tenants` | GET | Yes | List tenants for current user | | `/api/v1/tenants/current` | GET | Yes | Get current tenant | | `/api/v1/tenants/switch` | POST | Yes | Switch active tenant | ## Notifications | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/notifications` | GET | Yes | List notifications | | `/api/v1/notifications/{id}/read` | POST | Yes | Mark notification as read | | `/api/v1/notifications/read-all` | POST | Yes | Mark all as read | ## Import/Export | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/import/contacts` | POST | Yes | Import contacts from CSV/JSON | | `/api/v1/import/companies` | POST | Yes | Import companies from CSV/JSON | ## Plugins | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/plugins` | GET | Admin | List available plugins | | `/api/v1/plugins/{name}/install` | POST | Admin | Install a plugin | | `/api/v1/plugins/{name}/activate` | POST | Admin | Activate a plugin | | `/api/v1/plugins/{name}/deactivate` | POST | Admin | Deactivate a plugin | | `/api/v1/plugins/{name}/uninstall` | POST | Admin | Uninstall a plugin | ## AI Copilot | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/ai/chat` | POST | Yes | Send a message to the AI copilot | | `/api/v1/ai/conversations` | GET | Yes | List AI conversations | | `/api/v1/ai/conversations/{id}` | GET | Yes | Get conversation with messages | ## Workflows | Endpoint | Method | Auth | Description | |---|---|---|---| | `/api/v1/workflows` | GET | Yes | List workflows | | `/api/v1/workflows` | POST | Admin | Create a workflow | | `/api/v1/workflows/{id}` | GET | Yes | Get workflow details | | `/api/v1/workflows/{id}/start` | POST | Yes | Start a workflow instance | ## Pagination All list endpoints use cursor-based pagination with the following response format: ```json { "items": [...], "total": 1234, "page": 1, "page_size": 20 } ``` - `page_size` is capped at **100** (values >100 return HTTP 422). - `page` starts at 1. ## CSV Export Contacts and companies support streaming CSV export: ``` GET /api/v1/contacts/export?format=csv GET /api/v1/companies/export?format=csv ``` - Uses `StreamingResponse` — does not buffer the entire file in memory. - Streams rows in batches of 500 for memory efficiency. - Supports `search` filter for filtered exports. ## Swagger UI Interactive API documentation is available at: - **Swagger UI**: `http://localhost:8000/docs` - **ReDoc**: `http://localhost:8000/redoc` ## Error Format All errors return a consistent JSON structure: ```json { "detail": { "detail": "Human-readable error message", "code": "error_code" } } ``` Common status codes: - `200` — Success - `201` — Created - `204` — No content (delete success) - `400` — Bad request (invalid input) - `401` — Not authenticated - `403` — Forbidden (insufficient permissions) - `404` — Not found - `422` — Validation error (e.g., page_size > 100) - `500` — Internal server error