Every API here is available over the APIs.io API and to AI agents over MCP.
{"openapi":"3.0.0","paths":{"/api/notifications/push/public-key":{"get":{"operationId":"NotificationsController_pushPublicKey","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get the tenant VAPID public key for Web Push","tags":["Notifications"],"x-required-scope":["notifications:read"]}},"/api/notifications/push/subscribe":{"post":{"operationId":"NotificationsController_pushSubscribe","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushSubscribeDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Register a browser Web Push subscription","tags":["Notifications"],"x-required-scope":["notifications:write"]}},"/api/notifications/push/unsubscribe":{"post":{"operationId":"NotificationsController_pushUnsubscribe","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PushUnsubscribeDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Remove a browser Web Push subscription","tags":["Notifications"],"x-required-scope":["notifications:write"]}},"/api/notifications":{"get":{"operationId":"NotificationsController_findAll","parameters":[{"name":"dismissed","required":true,"in":"query","schema":{"type":"string"}},{"name":"type","required":true,"in":"query","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"pageSize","required":true,"in":"query","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List notifications for the current user","tags":["Notifications"]}},"/api/notifications/unread-count":{"get":{"operationId":"NotificationsController_unreadCount","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get the unread notifications badge count","tags":["Notifications"],"x-required-scope":["notifications:read"]}},"/api/notifications/read-all":{"post":{"operationId":"NotificationsController_readAll","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Mark all unread notifications as read","tags":["Notifications"],"x-required-scope":["notifications:write"]}},"/api/notifications/{id}/read":{"post":{"operationId":"NotificationsController_markRead","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Mark a notification as read","tags":["Notifications"]}},"/api/notifications/{id}/dismiss":{"post":{"operationId":"NotificationsController_dismiss","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Dismiss a notification (hide from widget)","tags":["Notifications"]}},"/api/notifications/dismiss-all":{"post":{"operationId":"NotificationsController_dismissAll","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Dismiss all notifications for the current user","tags":["Notifications"],"x-required-scope":["notifications:write"]}},"/api/notifications/self-note":{"post":{"operationId":"NotificationsController_createSelfNote","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSelfNoteDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Create an agent self-note notification","tags":["Notifications"],"x-required-scope":["notifications:write"]}},"/api/auth/register":{"post":{"operationId":"AuthController_register","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Register a new account (self-service). Requires termsAccepted=true (user agreement: GET /api/legal/terms). channel=web needs a password; channel=mcp/a2a/form (bootstrap from an AI agent) makes the password optional and returns the key as flat api_key/scope/quota fields (agent signup is rate-limited per IP). Creates User+Tenant with status=PENDING and emails a confirmation link (valid 48h) to the address. After the email is confirmed the account auto-activates — at most 1 auto-activation per hour platform-wide; beyond that it stays PENDING until admin approval (the admin is notified by email at every step). Self-signup workspaces have a 50MB database quota: over quota, POST/PUT/PATCH return 403 while reads and DELETE keep working. The auto-issued ldm_* key has SAFE_AGENT_SCOPES (read-all + safe drafts; no email:send / mailing:write) — mint a wider key in Settings → API Keys after activation.","tags":["Authentication"]}},"/api/auth/verify-email":{"get":{"operationId":"AuthController_verifyEmail","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}},{"name":"format","required":true,"in":"query","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Confirm email by the token from the signup email. Activates the account automatically (1 auto-activation per hour platform-wide; otherwise it stays PENDING for admin approval). Browsers are redirected to the login page with the result; API clients get JSON when ?format=json.","tags":["Authentication"]}},"/api/auth/signup-questionnaire":{"post":{"operationId":"AuthController_submitQuestionnaire","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupQuestionnaireDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Issue #322 — submit the signup questionnaire for accounts that did not qualify for automatic activation (free mailbox, or the website/MX checks did not line up). Authenticated by the signup_token from the verify-email redirect, not by an API key — the key issued at /auth/register stays inert until the account is ACTIVE. Calling this endpoint runs the automatic checks immediately (does the company domain resolve, does it answer over HTTP, does it match the contact mailbox) and saves the answers plus those results on the tenant record; it does NOT activate the account itself. The admin is emailed and approves the workspace as a separate, manual step (#1189: no ETA endpoint for that step). Until approval the account stays PENDING (read-only, cannot send email). Re-submitting overwrites the previous answers.","tags":["Authentication"]}},"/api/auth/otc":{"post":{"operationId":"AuthController_exchangeOtc","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Exchange the one-time sign-in code from the email-verification redirect for a session (same response as /auth/login). Codes are single-use and expire in 5 minutes.","tags":["Authentication"]}},"/api/auth/login":{"post":{"operationId":"AuthController_login","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Authenticate a user and issue access + refresh tokens. 401 = wrong email/password; 403 = credentials are correct but the account is not ACTIVE yet (email not confirmed / awaiting admin approval / blocked) — the error message says which.","tags":["Authentication"]}},"/api/auth/refresh":{"post":{"operationId":"AuthController_refresh","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Exchange a refresh token for a new access + refresh pair","tags":["Authentication"]}},"/api/auth/logout":{"post":{"operationId":"AuthController_logout","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Revoke a refresh token and end the session","tags":["Authentication"]}},"/api/auth/forgot-password":{"post":{"operationId":"AuthController_forgotPassword","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Request a password reset email (rate-limited per email and per IP)","tags":["Authentication"]}},"/api/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Reset password using a reset token","tags":["Authentication"]}},"/api/auth/profile":{"get":{"operationId":"AuthController_getProfile","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get the current authenticated user profile","tags":["Authentication"]}},"/api/auth/me":{"get":{"operationId":"AuthController_getMe","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get current user profile (alias of /auth/profile)","tags":["Authentication"]}},"/api/auth/change-password":{"post":{"operationId":"AuthController_changePassword","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Change the password of the authenticated user (current required)","tags":["Authentication"]}},"/api/auth/impersonate/{userId}":{"post":{"operationId":"AuthController_impersonate","parameters":[{"name":"userId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Impersonate another user (SUPER role only)","tags":["Authentication"]}},"/api/api-keys":{"get":{"operationId":"ApiKeysController_list","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List tenant API keys (raw key value hidden)","tags":["API Keys (tenant-scoped)"]},"post":{"operationId":"ApiKeysController_create","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Create a new tenant API key. Pass `actAsCurrentUser: true` to bind the key to the calling user (required for compose/reply/forward and other user-context endpoints; sets `ownerUserId`). Optional `scopes` array gates which surfaces the key can hit; default `[\"*\"]`.","tags":["API Keys (tenant-scoped)"]}},"/api/api-keys/whoami":{"get":{"operationId":"ApiKeysController_whoami","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Check that the current Bearer credentials (API key or JWT) are valid, and learn where this key is connected before hitting a wall. No scope required — any authenticated caller passes. Used by the MCP gateway to reject bad keys before building an MCP session, instead of after the first tool call. Beyond the original `{ ok, tenantId, scopes, authMode }`, also returns `baseUrl` (scheme+host the request actually arrived on, honoring x-forwarded-proto/x-forwarded-host behind the nginx edge), `apiPrefix` (the mandatory path prefix, taken from the same constant main.ts uses for setGlobalPrefix), and `closedCapabilityClasses` (LEGACY_CAPABILITIES id-prefix groups where NOT ONE operation is reachable with this key's granted scopes).","tags":["API Keys (tenant-scoped)"]}},"/api/api-keys/{id}/reveal":{"get":{"operationId":"ApiKeysController_reveal","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Reveal the raw value of an existing API key. Only JWT-authenticated (browser) calls are allowed — an ApiKey cannot read another key's secret. Returns { id, name, key }.","tags":["API Keys (tenant-scoped)"]}},"/api/api-keys/scopes/structured":{"get":{"operationId":"ApiKeysController_structuredScopes","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Structured scope catalog for the API Keys UI wizard. Returns presets (AI Agent / Read-only) + grouped scope definitions with descriptions and dangerous-flag. Used by Settings → API Keys to render the scope picker.","tags":["API Keys (tenant-scoped)"],"x-required-scope":["keys:read"]}},"/api/api-keys/{id}":{"patch":{"operationId":"ApiKeysController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Upgrade an existing API key in-place: set/unset Act-as-me. Only JWT-authenticated calls are allowed (an ApiKey cannot upgrade another ApiKey). Key value is NOT changed — downstream clients keep working without re-configuration.","tags":["API Keys (tenant-scoped)"]},"delete":{"operationId":"ApiKeysController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Permanently delete a tenant API key","tags":["API Keys (tenant-scoped)"]}},"/api/api-keys/{id}/revoke":{"delete":{"operationId":"ApiKeysController_revoke","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Revoke (deactivate) a tenant API key without deleting it","tags":["API Keys (tenant-scoped)"]}},"/api/webhooks":{"get":{"operationId":"WebhooksController_list","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List webhook endpoints","tags":["Webhooks"]},"post":{"operationId":"WebhooksController_create","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Create a webhook endpoint","tags":["Webhooks"]}},"/api/webhooks/{id}":{"patch":{"operationId":"WebhooksController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Update a webhook endpoint","tags":["Webhooks"]},"delete":{"operationId":"WebhooksController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Delete a webhook endpoint","tags":["Webhooks"]}},"/api/webhooks/{id}/deliveries":{"get":{"operationId":"WebhooksController_deliveries","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}},{"name":"status","required":true,"in":"query","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List delivery history for a webhook endpoint","tags":["Webhooks"]}},"/api/webhooks/deliveries/{id}/retry":{"post":{"operationId":"WebhooksController_retry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Retry a single webhook delivery","tags":["Webhooks"]}},"/api/webhooks/{id}/retrigger":{"post":{"operationId":"WebhooksController_retrigger","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Retrigger the last N deliveries for a webhook endpoint","tags":["Webhooks"]}},"/api/users/me/accept-terms":{"post":{"operationId":"UsersController_acceptTerms","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Accept legal terms for the current user","tags":["Users"],"x-required-scope":["users:write"]}},"/api/users":{"get":{"operationId":"UsersController_findAll","parameters":[{"name":"page","required":true,"in":"query","schema":{"type":"number"}},{"name":"pageSize","required":true,"in":"query","schema":{"type":"number"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List users (SUPER/MANAGER)","tags":["Users"]},"post":{"operationId":"UsersController_createUser","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Create a user (SUPER only)","tags":["Users"]}},"/api/users/system/stats":{"get":{"operationId":"UsersController_systemStats","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get system stats (SUPER only)","tags":["Users"],"x-required-scope":["users:read"]}},"/api/users/system/kill-process/{pid}":{"post":{"operationId":"UsersController_killProcess","parameters":[{"name":"pid","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Kill a system process by pid (SUPER only)","tags":["Users"]}},"/api/users/system/cleanup-orphans":{"post":{"operationId":"UsersController_cleanupOrphans","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Cleanup orphan system resources (SUPER only)","tags":["Users"],"x-required-scope":["users:write"]}},"/api/users/{id}":{"get":{"operationId":"UsersController_findById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get a user by id (SUPER/MANAGER)","tags":["Users"]},"delete":{"operationId":"UsersController_deleteUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Delete a user with tenant cleanup: sole-member tenants + their DBs are dropped (SUPER only)","tags":["Users"]}},"/api/users/{id}/role":{"patch":{"operationId":"UsersController_updateRole","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleDto"}}}},"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Update a user role (SUPER/MANAGER)","tags":["Users"]}},"/api/users/{id}/status":{"patch":{"operationId":"UsersController_updateStatus","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatusDto"}}}},"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Update a user status (SUPER/MANAGER)","tags":["Users"]}},"/api/users/{id}/password":{"patch":{"operationId":"UsersController_updatePassword","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePasswordDto"}}}},"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Update a user password (SUPER only)","tags":["Users"]}},"/api/users/{id}/profile":{"patch":{"operationId":"UsersController_updateProfile","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileDto"}}}},"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Update a user profile (SUPER only)","tags":["Users"]}},"/api/users/{id}/comments":{"get":{"operationId":"UsersController_listComments","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List admin comments on a user (SUPER/MANAGER)","tags":["Users"]},"post":{"operationId":"UsersController_addComment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCommentDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Add an admin comment on a user (SUPER/MANAGER)","tags":["Users"]}},"/api/users/{id}/comments/{commentId}":{"delete":{"operationId":"UsersController_deleteComment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"commentId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Delete an admin comment on a user (SUPER only)","tags":["Users"]}},"/api/companies/custom-fields":{"get":{"operationId":"CompanyCustomFieldController_getDefinitions","parameters":[{"name":"entity","required":true,"in":"query","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"List custom field definitions for the given entity (company/contact/lead)","tags":["Companies / Custom Fields"]},"post":{"operationId":"CompanyCustomFieldController_createDefinition","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCustomFieldDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Create a custom field definition","tags":["Companies / Custom Fields"]}},"/api/companies/custom-fields/reorder":{"put":{"operationId":"CompanyCustomFieldController_reorder","parameters":[{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Reorder custom field definitions by id array","tags":["Companies / Custom Fields"],"x-required-scope":["crm:write"]}},"/api/companies/custom-fields/{companyId}/values":{"get":{"operationId":"CompanyCustomFieldController_getValues","parameters":[{"name":"companyId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"responses":{"200":{"description":""}},"security":[{"jwt":[]}],"summary":"Get custom field values for a company","tags":["Companies / Custom Fields"]},"post":{"operationId":"CompanyCustomFieldController_setValues","parameters":[{"name":"companyId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Tenant-Id","in":"header","required":false,"schema":{"type":"string","format":"uuid"},"description":"Tenant UUID — required for all tenant-scoped endpoints"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetValuesDto"}}}},"responses":{"201":{"description":""}},"security":[{"jwt":[]}],"summary":"Set custom field values for a company","tags":["Companies / Custom Fields"]}},"/api/companies/custom-fields/{id}":{"put":{"operationId":"CompanyCustomFieldController_updateDefinition","parameters":[{"name":"id","required":true,"in":"
# --- truncated at 32 KB (823 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/live-direct-marketing-online/refs/heads/main/openapi/live-direct-marketing-online-ldm-v3-openapi.json