Files
pn-new-crm/08-API-ENDPOINT-CATALOG.md

576 lines
41 KiB
Markdown
Raw Normal View History

# Port Nimara CRM — API Endpoint Catalog
**Compiled:** 2026-03-11
**Pattern:** REST with Zod validation, JSON responses
**Auth:** Better Auth session cookies (internal), API key (webhooks), none (public)
**Docs:** OpenAPI/Swagger auto-generated at `/api-docs` for public endpoints
---
## Conventions
- All endpoints prefixed with `/api/`
- Port context from `X-Port-Id` header or session (middleware extracts and validates)
- Standard response shape: `{ data, meta?, error? }`
- Pagination: `?page=1&limit=25` → response includes `meta: { total, page, limit, pages }`
- Sorting: `?sort=field&order=asc|desc`
- Filtering: `?field=value` or `?field[op]=value` (e.g., `?status=available`, `?created_at[gte]=2025-01-01`)
- All write endpoints return the created/updated entity
- All delete endpoints return `{ success: true }`
- Error shape: `{ error: { code, message, details? } }`
- HTTP status codes: 200 (success), 201 (created), 400 (validation), 401 (unauthorized), 403 (forbidden), 404 (not found), 409 (conflict), 500 (server error)
---
## 1. Public API (No Auth)
Served to the website and external consumers. OpenAPI documented.
| Method | Path | Description |
| ------ | -------------------------- | -------------------------------------------------------------- |
| GET | `/api/public/berths` | List all berths with status and map data for website berth map |
| GET | `/api/public/berths/:id` | Single berth details for website detail view |
| POST | `/api/public/interests` | Website interest registration form submission |
| POST | `/api/public/forms/:token` | Pre-filled data collection form submission |
| GET | `/api/public/forms/:token` | Get form template + prefilled data for rendering |
Rate limited. CORS configured for allowed origins.
---
## 2. Authentication
| Method | Path | Description |
| ------ | ---------------------------------- | --------------------------------------------------------- |
| POST | `/api/auth/login` | Email + password login → session cookie |
| POST | `/api/auth/logout` | Destroy session |
| GET | `/api/auth/session` | Get current session (user info, port access, permissions) |
| POST | `/api/auth/password/set` | Set password from email link (token + new password) |
| POST | `/api/auth/password/reset-request` | Request password reset email |
| POST | `/api/auth/password/reset` | Reset password from email link (token + new password) |
---
## 3. Clients
| Method | Path | Description |
| ------ | --------------------------------------- | -------------------------------------------------------------------- |
| GET | `/api/clients` | List clients (paginated, filterable, sortable) |
| POST | `/api/clients` | Create client |
| GET | `/api/clients/:id` | Get client with contacts, tags, interest count |
| PATCH | `/api/clients/:id` | Update client fields |
| DELETE | `/api/clients/:id` | Soft delete (archive) client |
| POST | `/api/clients/:id/restore` | Restore archived client |
| GET | `/api/clients/:id/interests` | List all interests for this client |
| GET | `/api/clients/:id/timeline` | Activity timeline for this client |
| GET | `/api/clients/:id/files` | Files belonging to this client |
| GET | `/api/clients/:id/notes` | Notes on this client |
| POST | `/api/clients/:id/notes` | Add note to client |
| PATCH | `/api/clients/:id/notes/:noteId` | Edit note (within 15-min window) |
| GET | `/api/clients/:id/relationships` | Client relationships |
| POST | `/api/clients/:id/relationships` | Create relationship between clients |
| DELETE | `/api/clients/:id/relationships/:relId` | Remove relationship |
| POST | `/api/clients/merge` | Merge two clients (body: { surviving_id, merged_id, field_choices }) |
| GET | `/api/clients/duplicates` | List pending duplicate alerts |
| POST | `/api/clients/duplicates/:id/dismiss` | Dismiss a duplicate alert |
### Client Contacts
| Method | Path | Description |
| ------ | -------------------------------------- | -------------------- |
| GET | `/api/clients/:id/contacts` | List contact entries |
| POST | `/api/clients/:id/contacts` | Add contact entry |
| PATCH | `/api/clients/:id/contacts/:contactId` | Update contact entry |
| DELETE | `/api/clients/:id/contacts/:contactId` | Delete contact entry |
### Client Tags
| Method | Path | Description |
| ------ | ------------------------------ | ---------------------- |
| POST | `/api/clients/:id/tags` | Add tag(s) to client |
| DELETE | `/api/clients/:id/tags/:tagId` | Remove tag from client |
---
## 4. Interests
| Method | Path | Description |
| ------ | --------------------------------------------- | -------------------------------------------------------------------------------- |
| GET | `/api/interests` | List all interests (paginated, filterable by stage, berth, client, source, tags) |
| POST | `/api/interests` | Create interest (linked to client) |
| GET | `/api/interests/:id` | Get interest detail with client, berth, documents, milestones |
| PATCH | `/api/interests/:id` | Update interest fields |
| DELETE | `/api/interests/:id` | Soft delete (archive) interest |
| POST | `/api/interests/:id/restore` | Restore archived interest |
| PATCH | `/api/interests/:id/stage` | Change pipeline stage (with validation and auto-actions) |
| POST | `/api/interests/:id/berth` | Link berth to interest (auto-updates berth status) |
| DELETE | `/api/interests/:id/berth` | Unlink berth from interest (conditionally resets berth status) |
| GET | `/api/interests/:id/recommendations` | Get berth recommendations for this interest |
| POST | `/api/interests/:id/recommendations/generate` | Generate AI berth recommendations |
| POST | `/api/interests/:id/recommendations` | Add manual berth recommendation |
| GET | `/api/interests/:id/timeline` | Activity timeline for this interest |
| GET | `/api/interests/:id/notes` | Notes on this interest |
| POST | `/api/interests/:id/notes` | Add note to interest |
| PATCH | `/api/interests/:id/notes/:noteId` | Edit note (within 15-min window) |
| GET | `/api/interests/:id/documents` | Documents linked to this interest |
### Interest Tags
| Method | Path | Description |
| ------ | -------------------------------- | ------------------------ |
| POST | `/api/interests/:id/tags` | Add tag(s) to interest |
| DELETE | `/api/interests/:id/tags/:tagId` | Remove tag from interest |
---
## 5. Berths
| Method | Path | Description |
| ------- | ---------------------------------------------------- | --------------------------------------------------------------------- |
| GET | `/api/berths` | List berths (paginated, filterable by status, area, availability) |
| GET | `/api/berths/:id` | Get berth detail with linked interests, waiting list, maintenance log |
| PATCH | `/api/berths/:id` | Update berth fields |
| GET | `/api/berths/:id/map-data` | Get map rendering data |
| PATCH | `/api/berths/:id/map-data` | Update map rendering data |
| GET | `/api/berths/:id/interests` | List interests linked to this berth |
| GET | `/api/berths/:id/waiting-list` | Get waiting list for this berth |
| POST | `/api/berths/:id/waiting-list` | Add client to waiting list |
| PATCH | `/api/berths/:id/waiting-list/:entryId` | Update waiting list entry (position, priority) |
| DELETE | `/api/berths/:id/waiting-list/:entryId` | Remove from waiting list |
| GET | `/api/berths/:id/maintenance` | List maintenance log entries |
| POST | `/api/berths/:id/maintenance` | Add maintenance log entry |
| PATCH | `/api/berths/:id/maintenance/:logId` | Update maintenance entry |
| DELETE | `/api/berths/:id/maintenance/:logId` | Delete maintenance entry |
| POST | `/api/berths/:id/maintenance/:logId/photos` | Upload photos to maintenance log entry |
| DELETE | `/api/berths/:id/maintenance/:logId/photos/:photoId` | Remove photo from maintenance log |
| GET | `/api/berths/compare` | Compare berths (query: `?ids=id1,id2,id3`) |
| POST | `/api/berths/compare/export` | Export comparison as PDF |
| ~~GET~~ | ~~`/api/berths/availability-calendar`~~ | **CUT FROM V1** — Timeline view data deferred to post-V1 |
| POST | `/api/berths/import` | AI-assisted berth spec import (upload file) |
| GET | `/api/berths/import/:jobId` | Check import job status / get preview |
| POST | `/api/berths/import/:jobId/confirm` | Confirm and commit spec import |
### Berth Tags
| Method | Path | Description |
| ------ | ----------------------------- | --------------------- |
| POST | `/api/berths/:id/tags` | Add tag(s) to berth |
| DELETE | `/api/berths/:id/tags/:tagId` | Remove tag from berth |
---
## 6. Documents & Signing
| Method | Path | Description |
| ------ | ---------------------------------- | ----------------------------------------------------------------------- |
| GET | `/api/documents` | List documents (filterable by type, status, client, interest) |
| POST | `/api/documents` | Create document record |
| GET | `/api/documents/:id` | Get document detail with signers and events |
| PATCH | `/api/documents/:id` | Update document |
| DELETE | `/api/documents/:id` | Delete document |
| POST | `/api/documents/:id/send` | Send document for signing via Documenso |
| POST | `/api/documents/:id/upload-signed` | Upload manually signed document |
| POST | `/api/documents/:id/remind` | Send signing reminder |
| GET | `/api/documents/:id/signers` | List signers and their status |
| GET | `/api/documents/:id/events` | List signature events |
| POST | `/api/documents/generate-eoi` | Generate EOI from interest (auto-creates document + sends to Documenso) |
| POST | `/api/webhooks/documenso` | Documenso webhook receiver (signature events) |
### Document Templates
| Method | Path | Description |
| ------ | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| GET | `/api/document-templates` | List document templates (filterable by type, active status) |
| POST | `/api/document-templates` | Create document template |
| GET | `/api/document-templates/:id` | Get template detail with merge field definitions |
| PATCH | `/api/document-templates/:id` | Update template |
| DELETE | `/api/document-templates/:id` | Delete template |
| GET | `/api/document-templates/merge-fields` | List all available merge fields by source (client, interest, berth, port) |
| POST | `/api/document-templates/:id/generate` | Generate document from template (body: { clientId?, interestId?, berthId? }) — resolves merge fields, returns PDF |
| POST | `/api/document-templates/:id/generate-and-send` | Generate + email to client |
| POST | `/api/document-templates/:id/generate-and-sign` | Generate + send for Documenso signing |
### Record PDF Export
| Method | Path | Description |
| ------ | ------------------------------- | -------------------------------------- |
| POST | `/api/clients/:id/export-pdf` | Export client summary as branded PDF |
| POST | `/api/berths/:id/export-pdf` | Export berth spec sheet as branded PDF |
| POST | `/api/interests/:id/export-pdf` | Export interest summary as branded PDF |
---
## 7. Expenses
| Method | Path | Description |
| ------ | ------------------------------------- | ---------------------------------------------------------------------- |
| GET | `/api/expenses` | List expenses (paginated, filterable by date, category, payer, status) |
| POST | `/api/expenses` | Create expense |
| GET | `/api/expenses/:id` | Get expense detail |
| PATCH | `/api/expenses/:id` | Update expense |
| DELETE | `/api/expenses/:id` | Soft delete expense |
| POST | `/api/expenses/scan-receipt` | Upload receipt image → AI extraction → return parsed data |
| POST | `/api/expenses/export/csv` | Export filtered expenses as CSV |
| POST | `/api/expenses/export/pdf` | Export filtered expenses as PDF with receipt images |
| POST | `/api/expenses/export/parent-company` | Parent company export (expenses + receipts + EUR subtotal + 5% fee) |
---
## 8. Invoices
| Method | Path | Description |
| ------ | -------------------------------------- | ------------------------------------------------------------- |
| GET | `/api/invoices` | List invoices (paginated, filterable by status, date, client) |
| POST | `/api/invoices` | Create invoice (from line items or from grouped expenses) |
| GET | `/api/invoices/:id` | Get invoice detail with line items and linked expenses |
| PATCH | `/api/invoices/:id` | Update invoice |
| DELETE | `/api/invoices/:id` | Soft delete invoice |
| POST | `/api/invoices/:id/send` | Send invoice via email |
| POST | `/api/invoices/:id/generate-pdf` | Generate/regenerate invoice PDF |
| PATCH | `/api/invoices/:id/payment` | Record payment against invoice |
| GET | `/api/invoices/:id/line-items` | List line items |
| POST | `/api/invoices/:id/line-items` | Add line item |
| PATCH | `/api/invoices/:id/line-items/:itemId` | Update line item |
| DELETE | `/api/invoices/:id/line-items/:itemId` | Delete line item |
---
## 9. Files
| Method | Path | Description |
| ------ | -------------------------- | ------------------------------------------------- |
| GET | `/api/files` | List files (filterable by client, category, type) |
| POST | `/api/files/upload` | Upload file(s) to MinIO + create metadata |
| GET | `/api/files/:id` | Get file metadata |
| GET | `/api/files/:id/download` | Get presigned download URL |
| GET | `/api/files/:id/preview` | Get presigned preview URL (for PDFs/images) |
| PATCH | `/api/files/:id` | Update file metadata (rename, recategorize) |
| DELETE | `/api/files/:id` | Delete file (removes from MinIO + metadata) |
| POST | `/api/files/folders` | Create folder |
| PATCH | `/api/files/folders/:path` | Rename folder |
| DELETE | `/api/files/folders/:path` | Delete folder |
---
## 10. Email
| Method | Path | Description |
| ------ | ------------------------------ | ----------------------------------------- |
| GET | `/api/email/accounts` | List user's email accounts |
| POST | `/api/email/accounts` | Configure email account (SMTP/IMAP) |
| PATCH | `/api/email/accounts/:id` | Update email account settings |
| DELETE | `/api/email/accounts/:id` | Remove email account |
| POST | `/api/email/accounts/:id/test` | Test SMTP/IMAP connection |
| GET | `/api/email/threads` | List email threads (filterable by client) |
| GET | `/api/email/threads/:id` | Get thread with all messages |
| POST | `/api/email/send` | Compose and send email |
| POST | `/api/email/sync` | Trigger manual email sync |
---
## 11. Reminders
| Method | Path | Description |
| ------ | ----------------------------- | ---------------------------------------------------------------------------------- |
| GET | `/api/reminders` | List reminders (filterable by status, assignee, due date, priority, linked entity) |
| POST | `/api/reminders` | Create reminder (optional: `sync_to_calendar: true` to push to Google Calendar) |
| GET | `/api/reminders/:id` | Get reminder detail |
| PATCH | `/api/reminders/:id` | Update reminder (updates Google Calendar event if synced) |
| DELETE | `/api/reminders/:id` | Delete reminder (removes Google Calendar event if synced) |
| POST | `/api/reminders/:id/complete` | Mark reminder as completed |
| POST | `/api/reminders/:id/snooze` | Snooze reminder (body: `{ snooze_until }`) |
| POST | `/api/reminders/:id/dismiss` | Dismiss reminder |
| GET | `/api/reminders/my` | Current user's reminders |
| GET | `/api/reminders/overdue` | Overdue reminders |
| GET | `/api/reminders/upcoming` | Unified upcoming view: CRM reminders + Google Calendar events (next 14 days) |
## 11b. Google Calendar Integration
| Method | Path | Description |
| ------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| GET | `/api/calendar/auth-url` | Get Google OAuth 2.0 authorization URL |
| GET | `/api/calendar/callback` | OAuth callback — exchange code for tokens, store encrypted |
| GET | `/api/calendar/status` | Current user's calendar connection status (connected, calendar name, last sync) |
| GET | `/api/calendar/calendars` | List user's available Google Calendars (for calendar selection) |
| PATCH | `/api/calendar/settings` | Update calendar settings (selected calendar_id, sync_enabled) |
| POST | `/api/calendar/disconnect` | Disconnect Google Calendar (revoke token, clear cache) |
| POST | `/api/calendar/sync` | Trigger sync of Google Calendar events (called manually, on login, or on navigation to calendar-displaying pages if stale > 5 min) |
---
## 12. Notifications
| Method | Path | Description |
| ------ | ---------------------------------- | ----------------------------------------------- |
| GET | `/api/notifications` | List notifications for current user (paginated) |
| GET | `/api/notifications/unread-count` | Get unread notification count |
| PATCH | `/api/notifications/:id/read` | Mark notification as read |
| POST | `/api/notifications/mark-all-read` | Mark all as read |
| GET | `/api/notifications/preferences` | Get notification preferences |
| PATCH | `/api/notifications/preferences` | Update notification preferences |
---
## 13. Dashboard & Analytics
| Method | Path | Description |
| ------ | ------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| GET | `/api/dashboard` | Main dashboard data (pipeline, occupancy, revenue, recent activity, upcoming reminders + calendar events, overdue items) |
| GET | `/api/analytics/pipeline` | Pipeline analytics (counts/values by stage, conversion rates) |
| GET | `/api/analytics/revenue` | Revenue analytics (forecast, trends, breakdown) |
| GET | `/api/analytics/berths` | Berth analytics (occupancy, popularity, time-to-close) |
| GET | `/api/analytics/expenses` | Expense analytics (trends, categories, budgets) |
---
## 14. Search
| Method | Path | Description |
| ------ | -------------------- | --------------------------------------------------------------- |
| GET | `/api/search` | Global search across all entity types (query: `?q=search+term`) |
| GET | `/api/search/recent` | Recent searches for current user |
---
## 15. Tags
| Method | Path | Description |
| ------ | --------------- | ------------------------------ |
| GET | `/api/tags` | List all tags for current port |
| POST | `/api/tags` | Create tag |
| PATCH | `/api/tags/:id` | Update tag (name, color) |
| DELETE | `/api/tags/:id` | Delete tag |
---
## 16. Saved Views
| Method | Path | Description |
| ------ | ---------------------- | ------------------------------------------------------------- |
| GET | `/api/saved-views` | List saved views for current user (filterable by entity type) |
| POST | `/api/saved-views` | Create saved view |
| PATCH | `/api/saved-views/:id` | Update saved view |
| DELETE | `/api/saved-views/:id` | Delete saved view |
---
## 17. Scratchpad
| Method | Path | Description |
| ------ | -------------------------- | ------------------------------------ |
| GET | `/api/scratchpad` | List current user's scratchpad notes |
| POST | `/api/scratchpad` | Create scratchpad note |
| PATCH | `/api/scratchpad/:id` | Update note content |
| DELETE | `/api/scratchpad/:id` | Delete note |
| POST | `/api/scratchpad/:id/link` | Link note to a client record |
---
## 18. Import/Export
| Method | Path | Description |
| ------ | ------------------------- | ------------------------------------------------------------ |
| POST | `/api/import/upload` | Upload CSV/Excel for import (returns column mapping preview) |
| POST | `/api/import/preview` | Preview import with column mapping applied |
| POST | `/api/import/execute` | Execute import |
| GET | `/api/import/history` | List past imports |
| POST | `/api/export/:entityType` | Export entity list as CSV/Excel (body: filters, columns) |
---
## 19. Admin — User Management
| Method | Path | Description |
| ------ | ------------------------------------- | ------------------------------------------------- |
| GET | `/api/admin/users` | List all users |
| POST | `/api/admin/users` | Create user (sends "set password" email) |
| GET | `/api/admin/users/:id` | Get user detail with port assignments |
| PATCH | `/api/admin/users/:id` | Update user (activate/deactivate, update profile) |
| POST | `/api/admin/users/:id/reset-password` | Send password reset email |
| GET | `/api/admin/users/:id/activity` | User's recent activity |
---
## 20. Admin — Roles
| Method | Path | Description |
| ------ | ---------------------------------------- | --------------------------------------- |
| GET | `/api/admin/roles` | List all roles |
| POST | `/api/admin/roles` | Create role |
| GET | `/api/admin/roles/:id` | Get role detail with permissions |
| PATCH | `/api/admin/roles/:id` | Update role |
| DELETE | `/api/admin/roles/:id` | Delete role (blocked if users assigned) |
| GET | `/api/admin/roles/:id/overrides` | List per-port overrides for this role |
| POST | `/api/admin/roles/:id/overrides` | Create per-port override |
| PATCH | `/api/admin/roles/:id/overrides/:portId` | Update per-port override |
| DELETE | `/api/admin/roles/:id/overrides/:portId` | Remove per-port override |
---
## 21. Admin — Ports
| Method | Path | Description |
| ------ | ------------------------------------ | ----------------------------- |
| GET | `/api/admin/ports` | List all ports |
| POST | `/api/admin/ports` | Create port |
| GET | `/api/admin/ports/:id` | Get port detail |
| PATCH | `/api/admin/ports/:id` | Update port settings |
| POST | `/api/admin/ports/:id/assign-user` | Assign user to port with role |
| DELETE | `/api/admin/ports/:id/users/:userId` | Remove user from port |
---
## 22. Admin — Audit Log
| Method | Path | Description |
| ------ | ---------------------------------- | ---------------------------------------------------------------------------- |
| GET | `/api/admin/audit-logs` | List audit log entries (paginated, filterable by user, entity, action, date) |
| GET | `/api/admin/audit-logs/:id` | Get audit log entry detail (before/after values) |
| POST | `/api/admin/audit-logs/:id/revert` | Revert a specific change (super admin only) |
| POST | `/api/admin/audit-logs/export` | Export audit logs as CSV |
---
## 23. Admin — System
| Method | Path | Description |
| ------ | --------------------------------- | -------------------------------------- |
| GET | `/api/admin/settings` | Get all system settings |
| PATCH | `/api/admin/settings` | Update system settings |
| GET | `/api/admin/settings/:portId` | Get port-specific settings |
| PATCH | `/api/admin/settings/:portId` | Update port-specific settings |
| GET | `/api/admin/health` | System health check (all services) |
| POST | `/api/admin/backup` | Trigger manual database backup |
| GET | `/api/admin/backups` | List available backups |
| GET | `/api/admin/backups/:id/download` | Download backup file |
| POST | `/api/admin/backups/:id/restore` | Restore from backup (super admin only) |
---
## 24. Admin — Webhooks
| Method | Path | Description |
| ------ | ------------------------------------ | ---------------------------------- |
| GET | `/api/admin/webhooks` | List webhook configurations |
| POST | `/api/admin/webhooks` | Create webhook |
| GET | `/api/admin/webhooks/:id` | Get webhook detail |
| PATCH | `/api/admin/webhooks/:id` | Update webhook |
| DELETE | `/api/admin/webhooks/:id` | Delete webhook |
| GET | `/api/admin/webhooks/:id/deliveries` | List delivery log for this webhook |
| POST | `/api/admin/webhooks/:id/test` | Send test webhook payload |
---
## 25. Admin — Scheduled Reports
| Method | Path | Description |
| ------ | ---------------------------- | ---------------------------------- |
| GET | `/api/admin/reports` | List scheduled reports |
| POST | `/api/admin/reports` | Create scheduled report |
| GET | `/api/admin/reports/:id` | Get report detail |
| PATCH | `/api/admin/reports/:id` | Update report schedule/config |
| DELETE | `/api/admin/reports/:id` | Delete scheduled report |
| POST | `/api/admin/reports/:id/run` | Manually trigger report generation |
---
## 26. Admin — Custom Fields
| Method | Path | Description |
| ------ | ------------------------------ | --------------------------------------------------------- |
| GET | `/api/admin/custom-fields` | List custom field definitions (filterable by entity type) |
| POST | `/api/admin/custom-fields` | Create custom field definition |
| PATCH | `/api/admin/custom-fields/:id` | Update custom field definition |
| DELETE | `/api/admin/custom-fields/:id` | Delete custom field definition |
---
## 27. Admin — Forms
| Method | Path | Description |
| ------ | ------------------------------------------- | ------------------------------------------ |
| GET | `/api/admin/forms` | List form templates |
| POST | `/api/admin/forms` | Create form template |
| GET | `/api/admin/forms/:id` | Get form template detail |
| PATCH | `/api/admin/forms/:id` | Update form template |
| DELETE | `/api/admin/forms/:id` | Delete form template |
| GET | `/api/admin/forms/:id/submissions` | List submissions for this form |
| POST | `/api/admin/forms/:id/expire/:submissionId` | Manually expire a form submission link |
| POST | `/api/admin/forms/:id/regenerate` | Regenerate form link for a client/interest |
---
## 28. Admin — Monitoring
| Method | Path | Description |
| ------ | ----------------------------------------- | -------------------------------------------------- |
| GET | `/api/admin/jobs` | BullMQ job dashboard data (queues, counts, failed) |
| GET | `/api/admin/jobs/:queueName` | Jobs in a specific queue |
| POST | `/api/admin/jobs/:queueName/:jobId/retry` | Retry a failed job |
| DELETE | `/api/admin/jobs/:queueName/:jobId` | Delete a job |
| GET | `/api/admin/alerts` | Active system alerts |
| PATCH | `/api/admin/alerts/:id/acknowledge` | Acknowledge an alert |
---
## 29. Currency
| Method | Path | Description |
| ------ | ----------------------------- | ------------------------------------------------- |
| GET | `/api/currency/rates` | Get current exchange rates |
| POST | `/api/currency/rates/refresh` | Force refresh exchange rates from Frankfurter API |
| POST | `/api/currency/convert` | Convert amount between currencies |
| PATCH | `/api/currency/rates/:pair` | Manually override an exchange rate |
---
## 30. Bulk Operations
| Method | Path | Description |
| ------ | ------------------------- | ----------------------------------------------------------- |
| POST | `/api/bulk/status-change` | Bulk status change (body: { entity_type, ids, new_status }) |
| POST | `/api/bulk/tag` | Bulk tag assignment (body: { entity_type, ids, tag_ids }) |
| POST | `/api/bulk/export` | Bulk export (body: { entity_type, ids, format }) |
| POST | `/api/bulk/delete` | Bulk soft delete (body: { entity_type, ids }) |
---
## Endpoint Count Summary
| Section | Endpoints |
| --------------------- | ------------------ |
| Public API | 5 |
| Authentication | 6 |
| Clients | 22 |
| Interests | 19 |
| Berths | 22 |
| Documents | 12 |
| Document Templates | 9 |
| Record PDF Export | 3 |
| Expenses | 9 |
| Invoices | 12 |
| Files | 10 |
| Email | 9 |
| Reminders | 11 |
| Google Calendar | 7 |
| Notifications | 6 |
| Dashboard & Analytics | 5 |
| Search | 2 |
| Tags | 4 |
| Saved Views | 4 |
| Scratchpad | 5 |
| Import/Export | 5 |
| Admin — Users | 6 |
| Admin — Roles | 9 |
| Admin — Ports | 6 |
| Admin — Audit | 4 |
| Admin — System | 9 |
| Admin — Webhooks | 7 |
| Admin — Reports | 6 |
| Admin — Custom Fields | 4 |
| Admin — Forms | 6 |
| Admin — Monitoring | 6 |
| Currency | 4 |
| Bulk Operations | 4 |
| **TOTAL** | **~256 endpoints** |