{"schema_version":"1.0.0","name":"LDM.delivery","description":"Email delivery API for AI agents. Pay only for delivered inbox messages.","url":"https://api.live-direct-marketing.online","provider":{"organization":"Live Direct Marketing","url":"https://live-direct-marketing.online"},"auth":{"schemes":[{"type":"bearer","header":"Authorization","format":"ldm_...","obtain":"CRM Settings → API Keys"}]},"capabilities":[{"id":"AuthController_register","method":"POST","path":"/api/auth/register","summary":"Register a new account (self-service). Requires termsAccepted=true (user agreement: GET /api/legal/terms). 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. Returns { status, pending, message, limits, nextSteps, tenant, apiKey } — apiKey is a default ldm_* key with SAFE_AGENT_SCOPES (read-all + safe drafts; no email:send / mailing:write); mint a wider key in Settings → API Keys after login."},{"id":"AuthController_verifyEmail","method":"GET","path":"/api/auth/verify-email","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."},{"id":"AuthController_exchangeOtc","method":"POST","path":"/api/auth/otc","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."},{"id":"AuthController_login","method":"POST","path":"/api/auth/login","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."},{"id":"AuthController_refresh","method":"POST","path":"/api/auth/refresh","summary":"Exchange a refresh token for a new access + refresh pair"},{"id":"AuthController_logout","method":"POST","path":"/api/auth/logout","summary":"Revoke a refresh token and end the session"},{"id":"AuthController_forgotPassword","method":"POST","path":"/api/auth/forgot-password","summary":"Request a password reset email (rate-limited per email and per IP)"},{"id":"AuthController_resetPassword","method":"POST","path":"/api/auth/reset-password","summary":"Reset password using a reset token"},{"id":"AuthController_getProfile","method":"GET","path":"/api/auth/profile","summary":"Get the current authenticated user profile"},{"id":"AuthController_getMe","method":"GET","path":"/api/auth/me","summary":"Get current user profile (alias of /auth/profile)"},{"id":"AuthController_changePassword","method":"POST","path":"/api/auth/change-password","summary":"Change the password of the authenticated user (current required)"},{"id":"AuthController_impersonate","method":"POST","path":"/api/auth/impersonate/{userId}","summary":"Impersonate another user (SUPER role only)"},{"id":"keys.list","method":"GET","path":"/api/api-keys","scope":"keys:read","summary":"List tenant API keys (raw key value hidden)"},{"id":"keys.create","method":"POST","path":"/api/api-keys","scope":"keys:write","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 `[\"*\"]`."},{"id":"ApiKeysController_reveal","method":"GET","path":"/api/api-keys/{id}/reveal","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 }."},{"id":"ApiKeysController_structuredScopes","method":"GET","path":"/api/api-keys/scopes/structured","scope":"keys:read","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."},{"id":"ApiKeysController_update","method":"PATCH","path":"/api/api-keys/{id}","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."},{"id":"ApiKeysController_remove","method":"DELETE","path":"/api/api-keys/{id}","summary":"Permanently delete a tenant API key"},{"id":"ApiKeysController_revoke","method":"DELETE","path":"/api/api-keys/{id}/revoke","summary":"Revoke (deactivate) a tenant API key without deleting it"},{"id":"UsersController_acceptTerms","method":"POST","path":"/api/users/me/accept-terms","scope":"users:write","summary":"Accept legal terms for the current user"},{"id":"users.list","method":"GET","path":"/api/users","scope":"users:read","summary":"List users (SUPER/MANAGER)"},{"id":"users.create","method":"POST","path":"/api/users","scope":"users:write","summary":"Create a user (SUPER only)"},{"id":"UsersController_systemStats","method":"GET","path":"/api/users/system/stats","scope":"users:read","summary":"Get system stats (SUPER only)"},{"id":"UsersController_killProcess","method":"POST","path":"/api/users/system/kill-process/{pid}","summary":"Kill a system process by pid (SUPER only)"},{"id":"UsersController_cleanupOrphans","method":"POST","path":"/api/users/system/cleanup-orphans","scope":"users:write","summary":"Cleanup orphan system resources (SUPER only)"},{"id":"UsersController_findById","method":"GET","path":"/api/users/{id}","summary":"Get a user by id (SUPER/MANAGER)"},{"id":"UsersController_deleteUser","method":"DELETE","path":"/api/users/{id}","summary":"Delete a user with tenant cleanup: sole-member tenants + their DBs are dropped (SUPER only)"},{"id":"UsersController_updateRole","method":"PATCH","path":"/api/users/{id}/role","summary":"Update a user role (SUPER/MANAGER)"},{"id":"UsersController_updateStatus","method":"PATCH","path":"/api/users/{id}/status","summary":"Update a user status (SUPER/MANAGER)"},{"id":"UsersController_updatePassword","method":"PATCH","path":"/api/users/{id}/password","summary":"Update a user password (SUPER only)"},{"id":"UsersController_updateProfile","method":"PATCH","path":"/api/users/{id}/profile","summary":"Update a user profile (SUPER only)"},{"id":"UsersController_listComments","method":"GET","path":"/api/users/{id}/comments","summary":"List admin comments on a user (SUPER/MANAGER)"},{"id":"UsersController_addComment","method":"POST","path":"/api/users/{id}/comments","summary":"Add an admin comment on a user (SUPER/MANAGER)"},{"id":"UsersController_deleteComment","method":"DELETE","path":"/api/users/{id}/comments/{commentId}","summary":"Delete an admin comment on a user (SUPER only)"},{"id":"CompanyCustomFieldController_getDefinitions","method":"GET","path":"/api/companies/custom-fields","summary":"List custom field definitions for the given entity (company/contact/lead)"},{"id":"CompanyCustomFieldController_createDefinition","method":"POST","path":"/api/companies/custom-fields","summary":"Create a custom field definition"},{"id":"CompanyCustomFieldController_reorder","method":"PUT","path":"/api/companies/custom-fields/reorder","scope":"crm:write","summary":"Reorder custom field definitions by id array"},{"id":"CompanyCustomFieldController_getValues","method":"GET","path":"/api/companies/custom-fields/{companyId}/values","summary":"Get custom field values for a company"},{"id":"CompanyCustomFieldController_setValues","method":"POST","path":"/api/companies/custom-fields/{companyId}/values","summary":"Set custom field values for a company"},{"id":"CompanyCustomFieldController_updateDefinition","method":"PUT","path":"/api/companies/custom-fields/{id}","summary":"Update a custom field definition"},{"id":"CompanyCustomFieldController_deleteDefinition","method":"DELETE","path":"/api/companies/custom-fields/{id}","summary":"Delete a custom field definition (requires confirm=true)"},{"id":"DuplicatesController_getFields","method":"GET","path":"/api/companies/duplicates/fields","scope":"crm:read","summary":"List fields available for duplicate-scan matching"},{"id":"DuplicatesController_scan","method":"POST","path":"/api/companies/duplicates/scan","scope":"crm:read","summary":"Scan companies for duplicates by configured fields"},{"id":"DuplicatesController_merge","method":"POST","path":"/api/companies/duplicates/merge","scope":"crm:write","summary":"Merge duplicate company records"},{"id":"DuplicatesController_deleteDuplicates","method":"POST","path":"/api/companies/duplicates/delete","scope":"crm:write","summary":"Delete duplicate company records identified by scan"},{"id":"DuplicatesController_moveToList","method":"POST","path":"/api/companies/duplicates/move-to-list","scope":"crm:write","summary":"Move duplicate companies into a target list"},{"id":"CompaniesController_lookupInn","method":"GET","path":"/api/companies/inn/{inn}","summary":"Look up company information by Russian INN (tax ID)"},{"id":"CompaniesController_getStats","method":"GET","path":"/api/companies/stats","scope":"crm:read","summary":"Get company statistics, optionally scoped to a list"},{"id":"companies.list","method":"GET","path":"/api/companies","scope":"crm:read","summary":"List companies with pagination, search, and filters"},{"id":"companies.create","method":"POST","path":"/api/companies","scope":"crm:write","summary":"Create a new company. Note: `email` is NOT a Company field — emails live on linked contacts as Channels. Use POST /api/contacts to create the contact, then POST /api/contacts/:id/channels { type: \"EMAIL\", value } to attach an email channel. Passing `email` in this body returns 400."},{"id":"CompaniesController_findById","method":"GET","path":"/api/companies/{id}","summary":"Get a single company by ID"},{"id":"CompaniesController_update","method":"PATCH","path":"/api/companies/{id}","summary":"Update an existing company"},{"id":"CompaniesController_softDelete","method":"DELETE","path":"/api/companies/{id}","summary":"Soft-delete a company"},{"id":"CompaniesController_getTimeline","method":"GET","path":"/api/companies/{id}/timeline","summary":"Get a paginated timeline of events for a company"},{"id":"CompaniesController_bulk","method":"POST","path":"/api/companies/bulk","scope":"crm:write","summary":"Enqueue a bulk action on multiple companies (async)"},{"id":"CompaniesController_getBulkStatus","method":"GET","path":"/api/companies/bulk/{jobId}","summary":"Get the status of a bulk company job"},{"id":"CompaniesController_cancelBulk","method":"DELETE","path":"/api/companies/bulk/{jobId}","summary":"Cancel an in-progress bulk company job"},{"id":"CompaniesController_getExportColumns","method":"GET","path":"/api/companies/export/columns","scope":"crm:read","summary":"List exportable column definitions for companies"},{"id":"CompaniesController_exportCompanies","method":"POST","path":"/api/companies/export","scope":"crm:write","summary":"Export companies to a downloadable file"},{"id":"CompaniesController_findDuplicates","method":"GET","path":"/api/companies/duplicates","scope":"crm:read","summary":"Find duplicate companies in the workspace"},{"id":"CompaniesController_mergeCompanies","method":"POST","path":"/api/companies/merge","scope":"crm:write","summary":"Merge multiple companies into one keeper record"},{"id":"CompaniesController_importFromGoogleSheets","method":"POST","path":"/api/companies/import/google-sheets","scope":"crm:write","summary":"Fetch rows from a Google Sheets URL for import"},{"id":"CompaniesController_importPreview","method":"POST","path":"/api/companies/import/preview","scope":"crm:write","summary":"Preview a companies import with proposed mapping"},{"id":"CompaniesController_importStart","method":"POST","path":"/api/companies/import/start","scope":"crm:write","summary":"Start a companies import. Body: { rows: object[], mapping: {csvColumn -> field}, options }. Mappable fields: name (required), domain, inn, industry, size, country, city, address, phone, website, description, source. Deduplication is by DOMAIN or INN only (never by name — different legal entities share names): options.dedupeBy = \"auto\" (default: INN first, then domain) | \"inn\" | \"domain\"; options.duplicateHandling = \"skip\" (default) | \"update\" | \"create\". Also dedupes within the same batch. Returns { batchId, created, updated, skipped, errors, total, createdIds }; roll back with DELETE /import/rollback/{batchId}, add createdIds to a list via POST /company-lists/{id}/companies."},{"id":"CompaniesController_importCombined","method":"POST","path":"/api/companies/import/combined","scope":"crm:write","summary":"Combined companies + contacts import. mapping fields: company (name, domain, inn, industry, size, country, city, address, phone, website, source), custom fields cf:<key> → company.customFields (e.g. cf:Выручка, cf:Руководитель, cf:ОКВЭД), contact c:firstName/c:lastName/c:email/c:phone/c:position/c:personalEmail/c:linkedin. Company dedup by DOMAIN/INN only (options.dedupeBy=auto|inn|domain). If c:email present without c:firstName → a generic company contact is created (options.genericContactName, default «Общий контакт»). options.listId adds companies to a list. Returns {created,updated,skipped,errors,contactsCreated,createdIds,listId}."},{"id":"CompaniesController_enrichFromInn","method":"POST","path":"/api/companies/{id}/enrich-from-inn","summary":"Enrich a company from its INN via DaData"},{"id":"CompaniesController_restore","method":"POST","path":"/api/companies/{id}/restore","summary":"Restore a soft-deleted company"},{"id":"CompaniesController_rollbackImport","method":"DELETE","path":"/api/companies/import/rollback/{batchId}","summary":"Roll back a company import batch by ID"},{"id":"CompaniesController_freeze","method":"PATCH","path":"/api/companies/{id}/freeze","summary":"Freeze a company (set status FROZEN)"},{"id":"CompaniesController_unfreeze","method":"PATCH","path":"/api/companies/{id}/unfreeze","summary":"Unfreeze a company (set status ACTIVE)"},{"id":"agent.status","method":"GET","path":"/api/mail-agent/status","scope":"agent:read","summary":"Get the mail agent connection status and stats"},{"id":"agent.settings.get","method":"GET","path":"/api/mail-agent/settings","scope":"agent:read","summary":"Get current mail agent settings"},{"id":"agent.settings.toggle","method":"POST","path":"/api/mail-agent/settings","scope":"agent:write","summary":"Toggle the mail agent enabled flag"},{"id":"agent.token.regenerate","method":"POST","path":"/api/mail-agent/token/regenerate","scope":"agent:write","summary":"Regenerate the mail agent auth token"},{"id":"MailAgentController_resetStats","method":"POST","path":"/api/mail-agent/stats/reset","scope":"agent:write","summary":"Reset mail agent statistics counters"},{"id":"agent.disconnect","method":"POST","path":"/api/mail-agent/disconnect","scope":"agent:write","summary":"Disconnect the mail agent session"},{"id":"MailAgentController_downloadWindows","method":"GET","path":"/api/mail-agent/download/windows","scope":"agent:write","summary":"Download the Windows mail agent bundle with token pre-configured"},{"id":"MailAgentController_getQr","method":"GET","path":"/api/mail-agent/qr","scope":"agent:read","summary":"Get an SVG QR code for pairing the Android mail agent"},{"id":"MailAgentUpdateController_check","method":"GET","path":"/api/mail-agent/update/check","summary":"Check for the latest mail agent version (public)"},{"id":"notifications.list","method":"GET","path":"/api/notifications","scope":"notifications:read","summary":"List notifications for the current user"},{"id":"NotificationsController_unreadCount","method":"GET","path":"/api/notifications/unread-count","scope":"notifications:read","summary":"Get the unread notifications badge count"},{"id":"NotificationsController_markRead","method":"POST","path":"/api/notifications/{id}/read","summary":"Mark a notification as read"},{"id":"NotificationsController_dismiss","method":"POST","path":"/api/notifications/{id}/dismiss","summary":"Dismiss a notification (hide from widget)"},{"id":"NotificationsController_dismissAll","method":"POST","path":"/api/notifications/dismiss-all","scope":"notifications:write","summary":"Dismiss all notifications for the current user"},{"id":"ai.generate","method":"POST","path":"/api/ai/generate","scope":"ai:write","summary":"Generate AI completion via configured provider"},{"id":"AiController_getBalance","method":"GET","path":"/api/ai/balance","scope":"ai:read","summary":"Get balance for current or specified AI provider"},{"id":"AiController_getAllBalances","method":"GET","path":"/api/ai/balances","scope":"ai:read","summary":"Get balances for all configured AI providers"},{"id":"AiController_getUsage","method":"GET","path":"/api/ai/usage","scope":"ai:read","summary":"Get AI usage statistics for the given window (days)"},{"id":"AiController_getLogs","method":"GET","path":"/api/ai/logs","scope":"ai:read","summary":"Get recent AI usage logs"},{"id":"ai.providers","method":"GET","path":"/api/ai/providers","scope":"ai:read","summary":"List available AI providers with status"},{"id":"AiController_getModels","method":"GET","path":"/api/ai/models","scope":"ai:read","summary":"List available AI models per provider (dynamic)"},{"id":"AiController_checkBalance","method":"POST","path":"/api/ai/check-balance","scope":"ai:write","summary":"Check AI balance against threshold (cron/monitoring hook)"},{"id":"OAuthController_connectPage","method":"GET","path":"/api/oauth/connect","summary":"Public OAuth connect page for anti-detect browser flow"},{"id":"OAuthController_connectRedirect","method":"GET","path":"/api/oauth/connect/{accountId}","summary":"Public OAuth consent redirect for a specific account"},{"id":"OAuthController_getAuthUrl","method":"GET","path":"/api/oauth/auth-url/{accountId}","summary":"Get the OAuth consent URL for an email account"},{"id":"OAuthController_callback","method":"GET","path":"/api/oauth/callback","summary":"OAuth provider callback endpoint (public, used by provider redirect)"},{"id":"OAuthController_getStatus","method":"GET","path":"/api/oauth/{accountId}/status","summary":"Get OAuth connection status for an account"},{"id":"OAuthController_revoke","method":"POST","path":"/api/oauth/{accountId}/revoke","summary":"Revoke OAuth tokens for an account"},{"id":"OAuthController_refresh","method":"POST","path":"/api/oauth/{accountId}/refresh","summary":"Manually refresh the OAuth access token for an account"},{"id":"VariableResolverController_resolve","method":"POST","path":"/api/variable-resolver/resolve","summary":"Resolve contact context and variable map for templates"},{"id":"VariableResolverController_getAvailableVariables","method":"GET","path":"/api/variable-resolver/available-variables","summary":"List all variables exposed by the resolver"},{"id":"CreativeRulesController_get","method":"GET","path":"/api/creatives/{id}/rules","summary":"Get the creative rules document"},{"id":"CreativeRulesController_patch","method":"PATCH","path":"/api/creatives/{id}/rules","summary":"Patch the creative rules document"},{"id":"CreativeRulesController_getSchema","method":"GET","path":"/api/creatives/{id}/rules/schema","summary":"Get the JSON Schema for creative rules"},{"id":"CreativeRulesController_context","method":"GET","path":"/api/creatives/{id}/rules/context","summary":"Get supporting context used to evaluate creative rules"},{"id":"CreativeRulesController_history","method":"GET","path":"/api/creatives/{id}/rules/history","summary":"Get audit history of creative rule changes"},{"id":"CreativeBootstrapController_bootstrap","method":"GET","path":"/api/creatives/{id}/bootstrap","summary":"Get unified creative bootstrap snapshot for page render"},{"id":"CreativeBootstrapController_updateMeta","method":"PATCH","path":"/api/creatives/{id}/meta","summary":"Update creative meta fields (non-rule)"},{"id":"SubResourceRulesController_listSubResources","method":"GET","path":"/api/creatives/{id}/rules-sub","summary":"List available autopilot sub-resource keys"},{"id":"SubResourceRulesController_get","method":"GET","path":"/api/creatives/{id}/rules/{sub}","summary":"Get an autopilot sub-resource rules document"},{"id":"SubResourceRulesController_patch","method":"PATCH","path":"/api/creatives/{id}/rules/{sub}","summary":"Patch an autopilot sub-resource rules document"},{"id":"SubResourceRulesController_getSchema","method":"GET","path":"/api/creatives/{id}/rules/{sub}/schema","summary":"Get the JSON Schema for an autopilot sub-resource"},{"id":"SubResourceRulesController_history","method":"GET","path":"/api/creatives/{id}/rules/{sub}/history","summary":"Get audit history for an autopilot sub-resource"},{"id":"DiscoveryController_discovery","method":"GET","path":"/api/discovery","summary":"Get agent discovery document with resources and endpoints"},{"id":"DiscoveryController_contract","method":"GET","path":"/api/contract","summary":"Get the agent contract version and core principles"},{"id":"NalogIdController_lookup","method":"POST","path":"/api/nalog-id/lookup","summary":"Look up Russian tax/company data (Nalog) by company info"},{"id":"NalogIdController_test","method":"GET","path":"/api/nalog-id/test","summary":"Debug/test endpoint for Nalog lookup via query parameters"},{"id":"stoplist.list","method":"GET","path":"/api/stop-lists","scope":"stoplist:read","summary":"List stop list entries (user scope)"},{"id":"stoplist.add","method":"POST","path":"/api/stop-lists","scope":"stoplist:write","summary":"Add a stop list entry (user scope)"},{"id":"StopListController_stats","method":"GET","path":"/api/stop-lists/stats","scope":"stoplist:read","summary":"Get stop list statistics (user scope)"},{"id":"StopListController_addBulk","method":"POST","path":"/api/stop-lists/bulk","scope":"stoplist:write","summary":"Bulk-add stop list entries (user scope)"},{"id":"StopListController_remove","method":"DELETE","path":"/api/stop-lists/{id}","summary":"Remove a stop list entry (user scope)"},{"id":"stoplist.check","method":"POST","path":"/api/stop-lists/check","scope":"stoplist:read","summary":"Check a batch of emails against the stop list"},{"id":"StopListController_globalList","method":"GET","path":"/api/stop-lists/global","scope":"stoplist:read","summary":"List global stop list entries (SUPER only)"},{"id":"StopListController_globalAdd","method":"POST","path":"/api/stop-lists/global","scope":"stoplist:write","summary":"Add a global stop list entry (SUPER only)"},{"id":"StopListController_globalStats","method":"GET","path":"/api/stop-lists/global/stats","scope":"stoplist:read","summary":"Get global stop list statistics (SUPER only)"},{"id":"StopListController_globalAddBulk","method":"POST","path":"/api/stop-lists/global/bulk","scope":"stoplist:write","summary":"Bulk-add global stop list entries (SUPER only)"},{"id":"StopListController_globalRemove","method":"DELETE","path":"/api/stop-lists/global/{id}","summary":"Remove a global stop list entry (SUPER only)"},{"id":"suppression.list","method":"GET","path":"/api/suppression","scope":"suppression:read","summary":"List suppressed emails"},{"id":"suppression.add","method":"POST","path":"/api/suppression","scope":"suppression:write","summary":"Add an email to the suppression list"},{"id":"SuppressionController_addBulk","method":"POST","path":"/api/suppression/bulk","scope":"suppression:write","summary":"Bulk-add emails to the suppression list"},{"id":"suppression.check","method":"POST","path":"/api/suppression/check","scope":"suppression:read","summary":"Check a batch of emails against the suppression list"},{"id":"SuppressionController_remove","method":"DELETE","path":"/api/suppression/{email}","summary":"Remove an email from the suppression list"},{"id":"SuppressionController_listDomains","method":"GET","path":"/api/suppression/domains","scope":"suppression:read","summary":"List suppressed domains"},{"id":"SuppressionController_addDomain","method":"POST","path":"/api/suppression/domains","scope":"suppression:write","summary":"Add a domain to the suppression list"},{"id":"SuppressionController_removeDomain","method":"DELETE","path":"/api/suppression/domains/{domain}","summary":"Remove a domain from the suppression list"},{"id":"MailTransportController_stats","method":"GET","path":"/api/mail-transport/stats","scope":"mailing:read","summary":"Transport-usage breakdown from mail_outbox.sent_via. Useful for spotting unused or broken transports (e.g. relay=0 implies the option can be disabled)."},{"id":"ContactsController_getStats","method":"GET","path":"/api/contacts/stats","scope":"crm:read","summary":"Get contact statistics, optionally scoped to a list"},{"id":"ContactsController_findAllDuplicates","method":"GET","path":"/api/contacts/duplicates","scope":"crm:read","summary":"Find duplicate contacts across the workspace"},{"id":"contacts.list","method":"GET","path":"/api/contacts","scope":"crm:read","summary":"List contacts with pagination, search, and filters"},{"id":"contacts.create","method":"POST","path":"/api/contacts","scope":"crm:write","summary":"Create a new contact. Note: `email`/`phone` are NOT direct Contact fields — they live as Channels. After creating the contact, attach the email/phone via POST /api/contacts/:id/channels { type: \"EMAIL\" | \"PHONE\", value }. Passing `email`/`phone` in this body returns 400."},{"id":"ContactsController_findById","method":"GET","path":"/api/contacts/{id}","summary":"Get a single contact by ID"},{"id":"ContactsController_update","method":"PATCH","path":"/api/contacts/{id}","summary":"Update an existing contact"},{"id":"ContactsController_softDelete","method":"DELETE","path":"/api/contacts/{id}","summary":"Soft-delete a contact"},{"id":"ContactsController_getTimeline","method":"GET","path":"/api/contacts/{id}/timeline","summary":"Get a paginated timeline of events for a contact"},{"id":"ContactsController_bulk","method":"POST","path":"/api/contacts/bulk","scope":"crm:write","summary":"Массовое действие над контактами (async, BullMQ). Передай contactIds[] ЛИБО selectAll:true (сервер резолвит контакты по фильтру search/emailValidStatus/dig*). Действия: delete | addTags | removeTags | addToList | removeFromList | updateField; цель списка = параметр listId. ⚠️ Для addToList параметр listId служит И целью, И (при selectAll) фильтром-источником — поэтому selectAll НЕ добавит «всех в отдельный список» (фильтр по целевому списку вернёт его же членов, для пустого = 0). Флоу «собрать всю базу в список для рассылки»: (1) перечислить contactIds постранично (GET /contacts?hasEmail=true&page..) → addToList батчами (или contact-lists POST :id/contacts); (2) campaigns pour(listId). Контакт в списке — membership-строка, НЕ копия контакта."},{"id":"ContactsController_getBulkStatus","method":"GET","path":"/api/contacts/bulk/{jobId}","summary":"Get the status of a bulk contact job"},{"id":"ContactsController_cancelBulk","method":"DELETE","path":"/api/contacts/bulk/{jobId}","summary":"Cancel an in-progress bulk contact job"},{"id":"ContactsController_exportContacts","method":"POST","path":"/api/contacts/export","scope":"crm:write","summary":"Export contacts to a downloadable file"},{"id":"ContactsController_importPreview","method":"POST","path":"/api/contacts/import/preview","scope":"crm:write","summary":"Preview a contacts import with proposed mapping"},{"id":"ContactsController_importStart","method":"POST","path":"/api/contacts/import/start","scope":"crm:write","summary":"Start a contacts import job"},{"id":"ContactsController_restore","method":"POST","path":"/api/contacts/{id}/restore","summary":"Restore a soft-deleted contact"},{"id":"ContactsController_mergeContacts","method":"POST","path":"/api/contacts/merge","scope":"crm:write","summary":"Merge multiple contacts into one keeper record"},{"id":"ContactsController_triggerDig","method":"POST","path":"/api/contacts/{id}/dig","summary":"Manually trigger DIG email enrichment for a contact"},{"id":"ContactsController_checkDuplicates","method":"GET","path":"/api/contacts/{id}/duplicates","summary":"Check for duplicates of a specific contact"},{"id":"ContactsController_addChannel","method":"POST","path":"/api/contacts/{id}/channels","summary":"Add a communication channel to a contact"},{"id":"ContactsController_updateChannel","method":"PATCH","path":"/api/contacts/{contactId}/channels/{channelId}","summary":"Update a contact channel"},{"id":"ContactsController_deleteChannel","method":"DELETE","path":"/api/contacts/{contactId}/channels/{channelId}","summary":"Delete a contact channel"},{"id":"ContactsController_rollbackImport","method":"DELETE","path":"/api/contacts/import/rollback/{batchId}","summary":"Roll back a contact import batch by ID"},{"id":"ContactsController_findDuplicates","method":"GET","path":"/api/contacts/duplicates/by-email","scope":"crm:read","summary":"Find contacts that share duplicate email addresses"},{"id":"pipelines.list","method":"GET","path":"/api/pipelines","scope":"pipelines:read","summary":"List all pipelines"},{"id":"pipelines.create","method":"POST","path":"/api/pipelines","scope":"pipelines:write","summary":"Create a new pipeline"},{"id":"PipelinesController_getAllAutomationLogs","method":"GET","path":"/api/pipelines/automation-logs","scope":"pipelines:read","summary":"Get global automation logs across pipelines"},{"id":"PipelinesController_findById","method":"GET","path":"/api/pipelines/{id}","summary":"Get a single pipeline by ID"},{"id":"PipelinesController_update","method":"PATCH","path":"/api/pipelines/{id}","summary":"Update an existing pipeline"},{"id":"PipelinesController_remove","method":"DELETE","path":"/api/pipelines/{id}","summary":"Delete a pipeline"},{"id":"PipelinesController_createStage","method":"POST","path":"/api/pipelines/{id}/stages","summary":"Create a new stage in a pipeline"},{"id":"PipelinesController_reorderStages","method":"PATCH","path":"/api/pipelines/{pipelineId}/stages/reorder","summary":"Reorder pipeline stages"},{"id":"PipelinesController_updateStage","method":"PATCH","path":"/api/pipelines/{pipelineId}/stages/{stageId}","summary":"Update a pipeline stage"},{"id":"PipelinesController_removeStage","method":"DELETE","path":"/api/pipelines/{pipelineId}/stages/{stageId}","summary":"Delete a pipeline stage"},{"id":"PipelinesController_findAutomations","method":"GET","path":"/api/pipelines/stages/{stageId}/automations","summary":"List automations attached to a stage"},{"id":"PipelinesController_createAutomation","method":"POST","path":"/api/pipelines/stages/{stageId}/automations","summary":"Create an automation on a stage"},{"id":"PipelinesController_updateAutomation","method":"PATCH","path":"/api/pipelines/automations/{automationId}","summary":"Update a stage automation"},{"id":"PipelinesController_removeAutomation","method":"DELETE","path":"/api/pipelines/automations/{automationId}","summary":"Delete a stage automation"},{"id":"PipelinesController_getAutomationLogs","method":"GET","path":"/api/pipelines/automations/{automationId}/logs","summary":"Get execution logs for an automation"},{"id":"PipelinesController_getStats","method":"GET","path":"/api/pipelines/{id}/stats","summary":"Get stats and conversion metrics for a pipeline"},{"id":"PipelinesController_migrateLegacyStages","method":"POST","path":"/api/pipelines/{id}/migrate-legacy-stages","summary":"Migrate legacy denormalized stage JSON into PipelineStage rows"},{"id":"leads.list","method":"GET","path":"/api/leads","scope":"leads:read","summary":"List leads with pagination, search, and pipeline/stage filters"},{"id":"leads.create","method":"POST","path":"/api/leads","scope":"leads:write","summary":"Create a new lead"},{"id":"leads.stats","method":"GET","path":"/api/leads/stats","scope":"leads:read","summary":"Get lead statistics, optionally scoped to a pipeline"},{"id":"LeadsController_kanban","method":"GET","path":"/api/leads/kanban/{pipelineId}","summary":"Get the kanban board for a pipeline"},{"id":"LeadsController_kanbanStageMore","method":"GET","path":"/api/leads/kanban/{pipelineId}/stage/{stageId}","summary":"Load more leads for a single kanban stage"},{"id":"LeadsController_stages","method":"GET","path":"/api/leads/stages/{pipelineId}","summary":"List stages of a pipeline (for lead filters)"},{"id":"LeadsController_findDuplicates","method":"GET","path":"/api/leads/duplicates","scope":"leads:read","summary":"Find duplicate leads across the workspace (by title/contact/company within a pipeline)"},{"id":"LeadsController_findById","method":"GET","path":"/api/leads/{id}","summary":"Get a single lead by ID"},{"id":"LeadsController_update","method":"PATCH","path":"/api/leads/{id}","summary":"Update an existing lead"},{"id":"LeadsController_softDelete","method":"DELETE","path":"/api/leads/{id}","summary":"Soft-delete a lead"},{"id":"LeadsController_checkDuplicates","method":"GET","path":"/api/leads/{id}/duplicates","summary":"Check for duplicates of a specific lead"},{"id":"LeadsController_dossier","method":"GET","path":"/api/leads/{id}/dossier","summary":"Get the full dossier (company + contact + activity) for a lead"},{"id":"LeadsController_getInterest","method":"GET","path":"/api/leads/{id}/interest","summary":"Get the AI interest classification for a lead"},{"id":"LeadsController_setInterest","method":"PATCH","path":"/api/leads/{id}/interest","summary":"Manually set the interest status of a lead"},{"id":"LeadsController_interestBreakdown","method":"GET","path":"/api/leads/interest/breakdown","scope":"leads:read","summary":"Get the breakdown of leads by interest status"},{"id":"LeadsController_getDeal","method":"GET","path":"/api/leads/{id}/deal","summary":"Get the deal projection (amount/probability/weighted) for a lead"},{"id":"LeadsController_updateDeal","method":"PATCH","path":"/api/leads/{id}/deal","summary":"Update deal fields (amount/currency/probability/close date)"},{"id":"LeadsController_forecast","method":"GET","path":"/api/leads/deal/forecast","scope":"leads:read","summary":"Compute the weighted-amount forecast across leads in scope"},{"id":"LeadsController_move","method":"POST","path":"/api/leads/{id}/move","summary":"Move a lead to a different stage (and optionally pipeline)"},{"id":"LeadsController_bulk","method":"POST","path":"/api/leads/bulk","scope":"leads:write","summary":"Enqueue a bulk action on multiple leads (async)"},{"id":"LeadsController_getBulkStatus","method":"GET","path":"/api/leads/bulk/{jobId}","summary":"Get the status of a bulk lead job"},{"id":"LeadsController_cancelBulk","method":"DELETE","path":"/api/leads/bulk/{jobId}","summary":"Cancel an in-progress bulk lead job"},{"id":"LeadsController_restore","method":"POST","path":"/api/leads/{id}/restore","summary":"Restore a soft-deleted lead"},{"id":"leads.export","method":"POST","path":"/api/leads/export","scope":"leads:write","summary":"Export leads to a downloadable file"},{"id":"LeadsController_importPreview","method":"POST","path":"/api/leads/import/preview","scope":"leads:write","summary":"Preview a leads import with proposed mapping"},{"id":"leads.import","method":"POST","path":"/api/leads/import/start","scope":"leads:write","summary":"Start a leads import job"},{"id":"tags.list","method":"GET","path":"/api/tags","scope":"tags:read","summary":"List all tags in the workspace"},{"id":"tags.create","method":"POST","path":"/api/tags","scope":"tags:write","summary":"Create a new tag"},{"id":"TagsController_update","method":"PATCH","path":"/api/tags/{id}","summary":"Update an existing tag"},{"id":"TagsController_remove","method":"DELETE","path":"/api/tags/{id}","summary":"Delete a tag"},{"id":"TagsController_attachToCompany","method":"POST","path":"/api/tags/companies/{companyId}","summary":"Attach a tag to a company"},{"id":"TagsController_detachFromCompany","method":"DELETE","path":"/api/tags/companies/{companyId}/{tagId}","summary":"Detach a tag from a company"},{"id":"TagsController_attachToContact","method":"POST","path":"/api/tags/contacts/{contactId}","summary":"Attach a tag to a contact"},{"id":"TagsController_detachFromContact","method":"DELETE","path":"/api/tags/contacts/{contactId}/{tagId}","summary":"Detach a tag from a contact"},{"id":"TagsController_attachToLead","method":"POST","path":"/api/tags/leads/{leadId}","summary":"Attach a tag to a lead"},{"id":"TagsController_detachFromLead","method":"DELETE","path":"/api/tags/leads/{leadId}/{tagId}","summary":"Detach a tag from a lead"},{"id":"contact-lists.list","method":"GET","path":"/api/contact-lists","scope":"crm:read","summary":"List all contact lists for the tenant"},{"id":"ContactListsController_create","method":"POST","path":"/api/contact-lists","summary":"Create a new contact list"},{"id":"ContactListsController_update","method":"PATCH","path":"/api/contact-lists/{id}","summary":"Update a contact list"},{"id":"ContactListsController_remove","method":"DELETE","path":"/api/contact-lists/{id}","summary":"Delete a contact list"},{"id":"ContactListsController_reorder","method":"POST","path":"/api/contact-lists/reorder","scope":"crm:write","summary":"Reorder contact lists by id/sortOrder array"},{"id":"ContactListsController_addContacts","method":"POST","path":"/api/contact-lists/{id}/contacts","summary":"Add contacts to a list"},{"id":"ContactListsController_removeContacts","method":"DELETE","path":"/api/contact-lists/{id}/contacts","summary":"Remove contacts from a list"},{"id":"ContactListsController_duplicate","method":"POST","path":"/api/contact-lists/{id}/duplicate","summary":"Duplicate a contact list"},{"id":"ContactListsController_allStatistics","method":"GET","path":"/api/contact-lists/all-statistics","scope":"crm:read","summary":"Get statistics across all contact lists"},{"id":"ContactListsController_compare","method":"GET","path":"/api/contact-lists/compare","scope":"crm:read","summary":"Compare statistics between two contact lists"},{"id":"ContactListsController_statistics","method":"GET","path":"/api/contact-lists/{id}/statistics","summary":"Get statistics for a single contact list"},{"id":"ContactListGroupsController_findAll","method":"GET","path":"/api/contact-list-groups","summary":"List contact list groups (flat, with parentId for tree)"},{"id":"ContactListGroupsController_create","method":"POST","path":"/api/contact-list-groups","summary":"Create a contact list group"},{"id":"ContactListGroupsController_reorder","method":"POST","path":"/api/contact-list-groups/reorder","scope":"crm:write","summary":"Reorder contact list groups by id/sortOrder array"},{"id":"ContactListGroupsController_update","method":"PATCH","path":"/api/contact-list-groups/{id}","summary":"Update a contact list group (name/description/color/parent/sort)"},{"id":"ContactListGroupsController_remove","method":"DELETE","path":"/api/contact-list-groups/{id}","summary":"Delete a contact list group (children + lists are detached)"},{"id":"company-lists.list","method":"GET","path":"/api/company-lists","scope":"crm:read","summary":"List all company lists for the tenant"},{"id":"CompanyListsController_create","method":"POST","path":"/api/company-lists","summary":"Create a new company list"},{"id":"CompanyListsController_contactsCounts","method":"GET","path":"/api/company-lists/contacts-counts","scope":"crm:read","summary":"Sum of contacts of member companies, per list id (?ids=csv)"},{"id":"CompanyListsController_update","method":"PATCH","path":"/api/company-lists/{id}","summary":"Update a company list"},{"id":"CompanyListsController_remove","method":"DELETE","path":"/api/company-lists/{id}","summary":"Delete a company list"},{"id":"CompanyListsController_reorder","method":"POST","path":"/api/company-lists/reorder","scope":"crm:write","summary":"Reorder company lists by id/sortOrder array"},{"id":"CompanyListsController_addCompanies","method":"POST","path":"/api/company-lists/{id}/companies","summary":"Add companies to a list"},{"id":"CompanyListsController_removeCompanies","method":"DELETE","path":"/api/company-lists/{id}/companies","summary":"Remove companies from a list"},{"id":"CompanyListsController_duplicate","method":"POST","path":"/api/company-lists/{id}/duplicate","summary":"Duplicate a company list"},{"id":"CompanyListGroupsController_findAll","method":"GET","path":"/api/company-list-groups","summary":"List company list groups (flat, with parentId for tree)"},{"id":"CompanyListGroupsController_create","method":"POST","path":"/api/company-list-groups","summary":"Create a company list group"},{"id":"CompanyListGroupsController_reorder","method":"POST","path":"/api/company-list-groups/reorder","scope":"crm:write","summary":"Reorder company list groups by id/sortOrder array"},{"id":"CompanyListGroupsController_update","method":"PATCH","path":"/api/company-list-groups/{id}","summary":"Update a company list group (name/description/color/parent/sort)"},{"id":"CompanyListGroupsController_remove","method":"DELETE","path":"/api/company-list-groups/{id}","summary":"Delete a company list group (children + lists are detached)"},{"id":"CampaignGroupsController_findAll","method":"GET","path":"/api/campaign-groups","summary":"List campaign groups (flat, with parentId for tree)"},{"id":"CampaignGroupsController_create","method":"POST","path":"/api/campaign-groups","summary":"Create a campaign group"},{"id":"CampaignGroupsController_reorder","method":"POST","path":"/api/campaign-groups/reorder","scope":"crm:write","summary":"Reorder campaign groups by id/sortOrder array"},{"id":"CampaignGroupsController_update","method":"PATCH","path":"/api/campaign-groups/{id}","summary":"Update a campaign group (name/description/color/parent/sort)"},{"id":"CampaignGroupsController_remove","method":"DELETE","path":"/api/campaign-groups/{id}","summary":"Delete a campaign group (children + campaigns are detached)"},{"id":"settings.get","method":"GET","path":"/api/settings","scope":"settings:read","summary":"Get the full workspace settings document"},{"id":"SettingsController_updateAiProviders","method":"PATCH","path":"/api/settings/ai-providers","scope":"settings:write","summary":"Update AI provider keys and defaults"},{"id":"SettingsController_requestLdmAi","method":"POST","path":"/api/settings/ldm-ai/request","scope":"settings:write","summary":"Request LDM AI access / balance increase (tenant → admin)"},{"id":"SettingsController_updateNotifications","method":"PATCH","path":"/api/settings/notifications","scope":"settings:write","summary":"Update notification preferences (push and email)"},{"id":"settings.update","method":"PATCH","path":"/api/settings/workspace","scope":"settings:write","summary":"Update workspace metadata (name, currency, language)"},{"id":"SettingsController_getProfile","method":"GET","path":"/api/settings/profile","scope":"settings:read","summary":"Get the current user profile"},{"id":"SettingsController_updateProfile","method":"PATCH","path":"/api/settings/profile","scope":"settings:write","summary":"Update the current user profile"},{"id":"SettingsController_getUiPreferences","method":"GET","path":"/api/settings/ui-preferences","scope":"settings:read","summary":"Get current user UI preferences (dashboard blocks, left menu)"},{"id":"SettingsController_updateUiPreferences","method":"PATCH","path":"/api/settings/ui-preferences","scope":"settings:write","summary":"Replace current user UI preferences"},{"id":"SettingsController_uploadAvatar","method":"POST","path":"/api/settings/profile/avatar","scope":"settings:write","summary":"Upload a new avatar for the current user"},{"id":"SettingsController_deleteAvatar","method":"DELETE","path":"/api/settings/profile/avatar","scope":"settings:write","summary":"Delete the current user avatar"},{"id":"SettingsController_changePassword","method":"POST","path":"/api/settings/security/change-password","scope":"settings:write","summary":"Change the current user password"},{"id":"SettingsController_getSessions","method":"GET","path":"/api/settings/security/sessions","scope":"settings:read","summary":"List active sessions for the current user"},{"id":"SettingsController_revokeAllSessions","method":"DELETE","path":"/api/settings/security/sessions","scope":"settings:write","summary":"Revoke all active sessions for the current user"},{"id":"SettingsController_revokeSession","method":"DELETE","path":"/api/settings/security/sessions/{sessionId}","summary":"Revoke a single user session"},{"id":"SettingsController_getDadataIntegration","method":"GET","path":"/api/settings/integrations/dadata","scope":"settings:read","summary":"Get DaData integration configuration"},{"id":"SettingsController_updateDadataIntegration","method":"PATCH","path":"/api/settings/integrations/dadata","scope":"settings:write","summary":"Update DaData integration configuration"},{"id":"SettingsController_resetDadataCounter","method":"POST","path":"/api/settings/integrations/dadata/reset-counter","scope":"settings:write","summary":"Reset the DaData daily request counter"},{"id":"SettingsController_getInboxCheckIntegration","method":"GET","path":"/api/settings/integrations/inbox-check","scope":"settings:read","summary":"Get Inbox Check integration configuration"},{"id":"SettingsController_updateInboxCheckIntegration","method":"PATCH","path":"/api/settings/integrations/inbox-check","scope":"settings:write","summary":"Update Inbox Check integration configuration"},{"id":"SettingsController_testInboxCheckConnection","method":"POST","path":"/api/settings/integrations/inbox-check/test","scope":"settings:write","summary":"Test the Inbox Check connection"},{"id":"SettingsController_getTransports","method":"GET","path":"/api/settings/transports","scope":"settings:read","summary":"Get enabled mail transport flags"},{"id":"SettingsController_updateTransports","method":"PATCH","path":"/api/settings/transports","scope":"settings:write","summary":"Update enabled mail transport flags"},{"id":"SettingsController_listMailingAutoApprove","method":"GET","path":"/api/settings/mailing-auto-approve","scope":"settings:read","summary":"List users with mailing auto-approve enabled (SUPER only)"},{"id":"SettingsController_setMailingAutoApprove","method":"PATCH","path":"/api/settings/users/{userId}/mailing-auto-approve","summary":"Enable/disable mailing auto-approve for a user (SUPER only)"},{"id":"SettingsController_getTenantMailingAutoApprove","method":"GET","path":"/api/settings/mailing-auto-approve-tenant","scope":"settings:read","summary":"Get tenant-level mailing auto-approve — whether the WHOLE workspace sends without manual approval (SUPER only)"},{"id":"SettingsController_setTenantMailingAutoApprove","method":"PATCH","path":"/api/settings/mailing-auto-approve-tenant","scope":"settings:write","summary":"Set tenant-level mailing auto-approve. enabled=true → the whole workspace sends immediately after QC, no manual admin approval (overrides per-user). enabled=false → manual approval (or per-user trusted senders). SUPER only."},{"id":"SettingsController_getSendWindow","method":"GET","path":"/api/settings/send-window","scope":"settings:read","summary":"Get workspace send window (#194): { enabled, workDays[1-7], startTime, endTime, timezone } or null (24/7)"},{"id":"SettingsController_setSendWindow","method":"PATCH","path":"/api/settings/send-window","scope":"settings:write","summary":"Set workspace send window (#194). enabled=false → 24/7 (default). SUPER only."},{"id":"SettingsController_getMinSendInterval","method":"GET","path":"/api/settings/min-send-interval","scope":"settings:read","summary":"Get workspace default min send interval per account, seconds (#194). 0 = off"},{"id":"SettingsController_setMinSendInterval","method":"PATCH","path":"/api/settings/min-send-interval","scope":"settings:write","summary":"Set workspace default min send interval per account, seconds 0..86400 (#194). Per-account override lives on emailAccount.minSendIntervalSeconds. SUPER only."},{"id":"SettingsController_getPlatformTrackingAllowed","method":"GET","path":"/api/settings/platform-tracking-allowed","scope":"settings:read","summary":"Get whether SUPER allowed this tenant to serve the open-pixel via the SHARED platform domain (pixelSource=ldm). SUPER only. (#237)"},{"id":"SettingsController_setPlatformTrackingAllowed","method":"PATCH","path":"/api/settings/platform-tracking-allowed","scope":"settings:write","summary":"Allow/deny this tenant to serve the open-pixel via the SHARED platform domain (pixelSource=ldm). Default false — anti-spam gate so an unapproved tenant cannot burn the shared domain. SUPER only. (#237)"},{"id":"SettingsController_getNotifyRules","method":"GET","path":"/api/settings/notify-rules","scope":"settings:read","summary":"Get the notification routing rules"},{"id":"SettingsController_updateNotifyRules","method":"PATCH","path":"/api/settings/notify-rules","scope":"settings:write","summary":"Update the notification routing rules"},{"id":"SettingsController_getCrmEventRules","method":"GET","path":"/api/settings/crm-event-rules","scope":"settings:read","summary":"Get CRM event → notification bridge rules"},{"id":"SettingsController_updateCrmEventRules","method":"PATCH","path":"/api/settings/crm-event-rules","scope":"settings:write","summary":"Update CRM event → notification bridge rules"},{"id":"SettingsController_getMemoryNotes","method":"GET","path":"/api/settings/memory-notes","scope":"settings:read","summary":"Get the current user memory notes for AI features"},{"id":"SettingsController_updateMemoryNotes","method":"PATCH","path":"/api/settings/memory-notes","scope":"settings:write","summary":"Update the current user memory notes"},{"id":"SettingsController_deleteAllData","method":"DELETE","path":"/api/settings/delete-data","scope":"settings:write","summary":"Delete all tenant data (irreversible danger-zone action)"},{"id":"dialogs.list","method":"GET","path":"/api/dialogs","scope":"dialogs:read","summary":"List dialogs with filters (channel, status, folder, etc.)"},{"id":"DialogsController_getStats","method":"GET","path":"/api/dialogs/stats","scope":"dialogs:read","summary":"Get aggregate dialog statistics"},{"id":"DialogsController_getBadges","method":"POST","path":"/api/dialogs/badges","scope":"dialogs:read","summary":"Get bulk dialog badges for a set of leads"},{"id":"DialogsController_getAccounts","method":"GET","path":"/api/dialogs/accounts","scope":"dialogs:read","summary":"List email accounts used in dialogs"},{"id":"DialogsController_getFolders","method":"GET","path":"/api/dialogs/folders","scope":"dialogs:read","summary":"List folders, optionally scoped to an account"},{"id":"DialogsController_getThread","method":"GET","path":"/api/dialogs/thread/{threadId}","summary":"Get a full dialog thread by thread ID"},{"id":"DialogsController_bulk","method":"POST","path":"/api/dialogs/bulk","scope":"dialogs:write","summary":"Perform a bulk action on multiple dialogs"},{"id":"DialogsController_imapMove","method":"POST","path":"/api/dialogs/imap/move","scope":"dialogs:write","summary":"Move dialogs to an IMAP folder"},{"id":"DialogsController_imapDelete","method":"POST","path":"/api/dialogs/imap/delete","scope":"dialogs:write","summary":"Permanently delete dialogs from IMAP"},{"id":"DialogsController_imapListFolders","method":"GET","path":"/api/dialogs/imap/folders","scope":"dialogs:read","summary":"List IMAP folders live from the mail server"},{"id":"DialogsController_imapCreateFolder","method":"POST","path":"/api/dialogs/imap/folders","scope":"dialogs:write","summary":"Create an IMAP folder"},{"id":"DialogsController_imapRenameFolder","method":"PATCH","path":"/api/dialogs/imap/folders","scope":"dialogs:write","summary":"Rename an IMAP folder"},{"id":"DialogsController_imapDeleteFolder","method":"POST","path":"/api/dialogs/imap/folders/delete","scope":"dialogs:write","summary":"Delete an IMAP folder"},{"id":"DialogsController_getOutbox","method":"GET","path":"/api/dialogs/outbox","scope":"dialogs:read","summary":"List outbox entries with status and scheduling info"},{"id":"DialogsController_rescheduleOutbox","method":"PATCH","path":"/api/dialogs/outbox/{id}","summary":"Reschedule (or clear schedule on) a queued outbox send"},{"id":"DialogsController_cancelOutbox","method":"DELETE","path":"/api/dialogs/outbox/{id}","summary":"Cancel a queued or failed outbox entry"},{"id":"DialogsController_getOutboxStats","method":"GET","path":"/api/dialogs/outbox/stats","scope":"dialogs:read","summary":"Get outbox queue statistics"},{"id":"DialogsController_retryOutbox","method":"POST","path":"/api/dialogs/outbox/{id}/retry","summary":"Manually retry a failed outbox entry"},{"id":"DialogsController_refreshControlEmail","method":"POST","path":"/api/dialogs/outbox/{id}/refresh-control","summary":"Poll inbox-check for the placement status of a control email"},{"id":"DialogsController_resendControlEmail","method":"POST","path":"/api/dialogs/outbox/{id}/resend-control","summary":"Re-enqueue the control-copy send for an outbox entry"},{"id":"DialogsController_findById","method":"GET","path":"/api/dialogs/{id}","summary":"Get a single dialog by ID"},{"id":"DialogsController_update","method":"PATCH","path":"/api/dialogs/{id}","summary":"Update dialog metadata or edit a queued outbox message"},{"id":"DialogsController_remove","method":"DELETE","path":"/api/dialogs/{id}","summary":"Delete a dialog"},{"id":"DialogsController_markRead","method":"POST","path":"/api/dialogs/{id}/mark-read","summary":"Mark a dialog as read"},{"id":"DialogsController_toggleStar","method":"POST","path":"/api/dialogs/{id}/star","summary":"Toggle the starred flag on a dialog"},{"id":"DialogsController_snooze","method":"POST","path":"/api/dialogs/{id}/snooze","summary":"Snooze a dialog until a future timestamp"},{"id":"DialogsController_unsnooze","method":"POST","path":"/api/dialogs/{id}/unsnooze","summary":"Unsnooze a dialog immediately"},{"id":"DialogsController_setReminder","method":"POST","path":"/api/dialogs/{id}/reminder","summary":"Set a reminder on a dialog"},{"id":"DialogsController_clearReminder","method":"POST","path":"/api/dialogs/{id}/reminder/clear","summary":"Clear an existing reminder on a dialog"},{"id":"DialogsController_classifyReply","method":"POST","path":"/api/dialogs/{id}/classify-reply","summary":"Run AI reply classification on a dialog"},{"id":"DialogsController_markType","method":"POST","path":"/api/dialogs/{id}/mark-type","summary":"Manually mark the message type / marking of a dialog"},{"id":"DialogsController_actionUnsubscribe","method":"POST","path":"/api/dialogs/{id}/action/unsubscribe","summary":"Process an unsubscribe action triggered by a dialog"},{"id":"DialogsController_actionBounce","method":"POST","path":"/api/dialogs/{id}/action/bounce","summary":"Process a bounce action (hard or soft) on a dialog"},{"id":"DialogsController_actionSpam","method":"POST","path":"/api/dialogs/{id}/action/spam","summary":"Mark a dialog as spam and apply side effects"},{"id":"DialogsController_actionStopList","method":"POST","path":"/api/dialogs/{id}/action/stop-list","summary":"Add the dialog sender to the stop-list"},{"id":"DialogsController_generateReply","method":"POST","path":"/api/dialogs/{id}/generate-reply","summary":"Generate an AI reply draft for a dialog"},{"id":"DialogsController_reply","method":"POST","path":"/api/dialogs/{id}/reply","summary":"Reply to a dialog (optionally send via SMTP with attachments). Attachments can be passed inline as `attachmentsJson: [{ filename, contentBase64, contentType }]` (base64-encoded, JSON body) or as multipart files. (#175 — parity with /compose)"},{"id":"DialogsController_forward","method":"POST","path":"/api/dialogs/{id}/forward","summary":"Forward an existing dialog to a new recipient. Attachments can be passed inline as `attachmentsJson: [{ filename, contentBase64, contentType }]` (base64-encoded, JSON body) or as multipart files. (#175 — parity with /compose)"},{"id":"dialogs.compose","method":"POST","path":"/api/dialogs/compose","scope":"dialogs:write","summary":"Compose and send a new outbound email. Provide exactly one sender binding: `accountId` (a fixed relay) OR `accountListId` (a virtual-relay pool — the live relay is chosen from the pool at dispatch time, #40). Attachments can be passed inline as `attachmentsJson: [{ filename, contentBase64, contentType }]` (base64-encoded), or as multipart files via /compose-multipart. (#3 Block 3 — inline attachments)"},{"id":"DialogsController_autoLink","method":"POST","path":"/api/dialogs/{id}/auto-link","summary":"Auto-link a dialog to matching contact/company/lead"},{"id":"DialogsController_createLead","method":"POST","path":"/api/dialogs/{id}/create-lead","summary":"Create a new lead from a dialog"},{"id":"DialogsController_extractEntities","method":"POST","path":"/api/dialogs/{id}/extract-entities","summary":"Run AI entity extraction (company/contact) on a dialog"},{"id":"DialogsController_setTrackingToken","method":"POST","path":"/api/dialogs/{id}/track/set-token","summary":"Set the tracking token on a dialog (internal use)"},{"id":"DialogsController_trackOpen","method":"POST","path":"/api/dialogs/track/open","scope":"dialogs:write","summary":"Record an email-open tracking event"},{"id":"DialogsController_trackClick","method":"POST","path":"/api/dialogs/track/click","scope":"dialogs:write","summary":"Record an email-click tracking event"},{"id":"DialogsController_restore","method":"POST","path":"/api/dialogs/{id}/restore","summary":"Restore a deleted dialog (status DELETED → NEW)"},{"id":"DialogsController_shareDialog","method":"POST","path":"/api/dialogs/{id}/share","summary":"Generate a public share token for a dialog (30-day TTL)"},{"id":"user-settings.get","method":"GET","path":"/api/user-settings","scope":"settings:read","summary":"Get current user settings"},{"id":"UserSettingsController_update","method":"PATCH","path":"/api/user-settings","summary":"Update current user settings"},{"id":"UserSettingsController_availableTransports","method":"GET","path":"/api/user-settings/available-transports","scope":"settings:read","summary":"List available transports admin has enabled"},{"id":"mailing.overview","method":"GET","path":"/api/mailing/overview","scope":"mailing:read","summary":"Get a global overview of all mailing campaigns (admin dashboard)"},{"id":"MailingController_getBounceOverview","method":"GET","path":"/api/mailing/bounce-overview","scope":"mailing:read","summary":"Get global bounce statistics across all campaigns"},{"id":"MailingController_getWarmupOverview","method":"GET","path":"/api/mailing/warmup-overview","scope":"mailing:read","summary":"Get an overview of all email accounts currently in warmup mode"},{"id":"mailing.pending","method":"GET","path":"/api/mailing/pending-approvals","scope":"mailing:read","summary":"List campaigns awaiting admin approval (cross-tenant for SUPER)"},{"id":"MailingController_approveCampaign","method":"POST","path":"/api/mailing/{taskId}/approve","summary":"Approve a pending mailing campaign (admin)"},{"id":"MailingController_rejectCampaign","method":"POST","path":"/api/mailing/{taskId}/reject","summary":"Reject a pending mailing campaign (admin)"},{"id":"MailingController_getCreativePreview","method":"GET","path":"/api/mailing/creative-preview/{creativeId}","summary":"Preview a creative for approval (cross-tenant for SUPER)"},{"id":"MailingController_getConfig","method":"GET","path":"/api/mailing/{taskId}/config","summary":"Get the mailing configuration for a campaign"},{"id":"MailingController_updateConfig","method":"PATCH","path":"/api/mailing/{taskId}/config","summary":"Update the mailing configuration for a campaign"},{"id":"MailingController_startCampaign","method":"POST","path":"/api/mailing/{taskId}/start","summary":"Start a mailing campaign"},{"id":"MailingController_startSending","method":"POST","path":"/api/mailing/{taskId}/start-sending","summary":"Issue #180: старт отправки СОГЛАСОВАННОЙ кампании (status=APPROVED). Отдельный шаг после согласования — запускает стримы → ACTIVE. 400 если не согласована или креатив изменён после согласования (нужно пересогласовать)."},{"id":"MailingController_getBatchStats","method":"POST","path":"/api/mailing/batch-stats","scope":"mailing:write","summary":"Get stats for a batch of mailing tasks in one call"},{"id":"MailingController_getStartListStats","method":"GET","path":"/api/mailing/{taskId}/start-list-stats","summary":"Get start-list statistics for a mailing campaign"},{"id":"MailingController_getStats","method":"GET","path":"/api/mailing/{taskId}/stats","summary":"Get aggregate stats for a mailing campaign"},{"id":"MailingController_getTimeline","method":"GET","path":"/api/mailing/{taskId}/timeline","summary":"Get the activity timeline for a mailing campaign"},{"id":"MailingController_getSpeed","method":"GET","path":"/api/mailing/{taskId}/speed","summary":"Get sending speed metrics for a mailing campaign"},{"id":"MailingController_getStreams","method":"GET","path":"/api/mailing/{taskId}/streams","summary":"List sending streams for a mailing campaign"},{"id":"MailingController_getStreamLogs","method":"GET","path":"/api/mailing/{taskId}/streams/{streamId}/logs","summary":"Get logs for a specific mailing stream"},{"id":"MailingController_getStreamDetail","method":"GET","path":"/api/mailing/{taskId}/streams/{streamId}/detail","summary":"Get detailed information for a specific mailing stream"},{"id":"MailingController_getStreamLogsFiltered","method":"GET","path":"/api/mailing/{taskId}/streams/{streamId}/logs-filtered","summary":"Get filtered and paginated logs for a mailing stream"},{"id":"MailingController_deleteTaskLogs","method":"DELETE","path":"/api/mailing/{taskId}/logs","summary":"Delete all logs for a mailing campaign"},{"id":"MailingController_getItems","method":"GET","path":"/api/mailing/{taskId}/items","summary":"List mailing items (recipients) for a campaign"},{"id":"MailingController_getItem","method":"GET","path":"/api/mailing/{taskId}/items/{itemId}","summary":"Get a single mailing item by id"},{"id":"MailingController_updateItem","method":"PATCH","path":"/api/mailing/{taskId}/items/{itemId}","summary":"Update fields of a single mailing item"},{"id":"MailingController_updateItemStatus","method":"PATCH","path":"/api/mailing/{taskId}/items/{itemId}/status","summary":"Update the status of a single mailing item"},{"id":"MailingController_resetErrors","method":"POST","path":"/api/mailing/{taskId}/reset-errors","summary":"Reset all failed mailing items in a campaign back to pending"},{"id":"MailingController_resetByStatus","method":"POST","path":"/api/mailing/{taskId}/reset-status/{status}","summary":"Reset all items with a given status back to pending"},{"id":"MailingController_getStatsToday","method":"GET","path":"/api/mailing/{taskId}/stats/today","summary":"Get today's stats for a mailing campaign"},{"id":"MailingController_getAbTest","method":"GET","path":"/api/mailing/{taskId}/ab-test","summary":"Get A/B test statistics for a mailing campaign"},{"id":"MailingController_getAnalytics","method":"GET","path":"/api/mailing/{taskId}/analytics","summary":"Get per-domain analytics for a mailing campaign"},{"id":"MailingController_getControlEmailStats","method":"GET","path":"/api/mailing/{taskId}/control-email-stats","summary":"Get control-email tracking stats for a mailing campaign"},{"id":"MailingController_evaluateControlEmailAutoPause","method":"POST","path":"/api/mailing/{taskId}/control-email-autopause/evaluate","summary":"Manually evaluate control-email auto-pause rules for a campaign"},{"id":"MailingController_exportCsv","method":"GET","path":"/api/mailing/{taskId}/export.csv","summary":"Export a mailing campaign as CSV"},{"id":"MailingController_exportReportPdf","method":"GET","path":"/api/mailing/{taskId}/report.pdf","summary":"Export a client-ready PDF report for a mailing campaign"},{"id":"MailingController_blockGuardDashboard","method":"GET","path":"/api/mailing/block-guard/dashboard","scope":"mailing:read","summary":"Get the BlockGuard dashboard (blocks, barked templates, paused accounts)"},{"id":"MailingController_blockGuardTemplate","method":"GET","path":"/api/mailing/block-guard/template/{templateId}","summary":"Get block-event history for a template"},{"id":"MailingController_blockGuardUnblock","method":"POST","path":"/api/mailing/block-guard/template/{templateId}/unblock","summary":"Manually unblock a previously barked template"},{"id":"MailingController_blockGuardAccount","method":"GET","path":"/api/mailing/block-guard/account/{accountId}","summary":"Get block-event history for an email account"},{"id":"MailingController_blockGuardProviders","method":"GET","path":"/api/mailing/block-guard/providers","scope":"mailing:read","summary":"Get block statistics aggregated per email provider"},{"id":"TrackingController_pixelOpen","method":"GET","path":"/api/t/o/{trackingId}.gif","summary":"Serve a 1x1 tracking pixel GIF and log an OPEN event. Injected into campaign emails; drives open-rate analytics."},{"id":"TrackingController_clickRedirect","method":"GET","path":"/api/t/c/{trackingId}/{slug}","summary":"Redirect a tracked click (/t/c/:trackingId/:slug) to target and log a CLICK. Cloaking: cloakMode=bot_split → bots go to botDecoyUrl (logs BOT_CLICK), humans to target; cloakMode=captcha → HTML interstitial unless a valid ?v token is present. This mapped path is produced by campaign sends and feeds analytics."},{"id":"TrackingController_legacyRedirect","method":"GET","path":"/api/r/{slug}","summary":"Short redirect by slug (/r/:slug) — click path for directly-created links (createLink). Applies the same cloaking (bot_split / captcha via ?v) but does NOT log tracking events, so this path produces no analytics."},{"id":"TrackingController_createLink","method":"POST","path":"/api/tracking/links","scope":"mailing:write","summary":"Create a tracking link. Optional cloakMode (off|bot_split|captcha) + botDecoyUrl enable cloaking immediately, no send required. Such links are clicked via /r/:slug (legacyRedirect) and do NOT log events — for open/click-rate analytics send links through a campaign (senderConfig.tracking)."},{"id":"TrackingController_getLinkInfo","method":"GET","path":"/api/tracking/links/{slug}","summary":"Get tracking link info by slug"},{"id":"TrackingController_updateLink","method":"PATCH","path":"/api/tracking/links/{slug}","summary":"Update a tracking link: cloakMode (off|bot_split|captcha), botDecoyUrl and/or targetUrl. Only provided fields change."},{"id":"TrackingController_deleteLink","method":"DELETE","path":"/api/tracking/links/{slug}","summary":"Delete a tracking link by slug"},{"id":"TrackingController_simulateClick","method":"POST","path":"/api/tracking/simulate-click","scope":"mailing:read","summary":"Dry-run the cloaking decision for a link given userAgent/ip/v — returns target|decoy|captcha + bot verdict WITHOUT logging an event or moving counters. Lets an agent test cloakMode (off/bot_split/captcha) without spoofing HTTP headers."},{"id":"TrackingController_getEvents","method":"GET","path":"/api/tracking/events","scope":"mailing:read","summary":"List raw tracking events (type filter: OPEN | CLICK | BOT_CLICK). Populated by campaign-sent links (mapped /t/c path + pixel); directly-created links clicked via /r do not appear here."},{"id":"TrackingController_getStats","method":"GET","path":"/api/tracking/stats","scope":"mailing:read","summary":"Get aggregated tracking stats for a task"},{"id":"TrackingController_getPixelSettings","method":"GET","path":"/api/tracking/pixel-settings","scope":"mailing:read","summary":"Get tenant pixel tracking settings"},{"id":"TrackingController_updatePixelSettings","method":"PATCH","path":"/api/tracking/pixel-settings","scope":"mailing:write","summary":"Update tenant pixel tracking settings"},{"id":"TrackingController_getAnalyticsStats","method":"GET","path":"/api/tracking/analytics/stats","scope":"mailing:read","summary":"Aggregated tracking analytics (open rate, click rate, unique opens/clicks). Populated only from campaign-sent tracking (pixel + mapped click path); directly-created createLink links produce no analytics."},{"id":"TrackingController_getTimeline","method":"GET","path":"/api/tracking/analytics/timeline","scope":"mailing:read","summary":"Get opens/clicks timeline"},{"id":"TrackingController_getTopLinks","method":"GET","path":"/api/tracking/analytics/top-links","scope":"mailing:read","summary":"Top clicked links with per-link click counts (from campaign-sent CLICK events)."},{"id":"TrackingController_getEmailClients","method":"GET","path":"/api/tracking/analytics/email-clients","scope":"mailing:read","summary":"Get email client distribution from tracking events"},{"id":"TrackingController_getDevices","method":"GET","path":"/api/tracking/analytics/devices","scope":"mailing:read","summary":"Get device type distribution from tracking events"},{"id":"TrackingDomainController_findAll","method":"GET","path":"/api/tracking-domains","summary":"List tracking domains"},{"id":"TrackingDomainController_create","method":"POST","path":"/api/tracking-domains","summary":"Create a tracking domain (starts as PENDING). External step: add a DNS CNAME <domain> → cnameTarget (default track.pixel.ldm-app.com) in the customer DNS zone, then run health-check/verify to make it ACTIVE. An ACTIVE domain is required for campaign link rewriting; set one as default for the open pixel."},{"id":"TrackingDomainController_getStats","method":"GET","path":"/api/tracking-domains/stats","scope":"mailing:read","summary":"Get tracking domain statistics"},{"id":"TrackingDomainController_findOne","method":"GET","path":"/api/tracking-domains/{id}","summary":"Get a tracking domain by id"},{"id":"TrackingDomainController_update","method":"PUT","path":"/api/tracking-domains/{id}","summary":"Update a tracking domain"},{"id":"TrackingDomainController_remove","method":"DELETE","path":"/api/tracking-domains/{id}","summary":"Delete a tracking domain"},{"id":"TrackingDomainController_healthCheck","method":"POST","path":"/api/tracking-domains/{id}/health-check","summary":"Run a health check for a tracking domain (verifies the DNS CNAME → cnameTarget and SSL). Passing DNS moves a PENDING domain toward ACTIVE."},{"id":"TrackingDomainController_setDefault","method":"POST","path":"/api/tracking-domains/{id}/set-default","summary":"Set a tracking domain as the default (used for the open pixel; without a default the pixel falls back to APP_URL/api)."},{"id":"TrackingDomainController_getMonitoring","method":"GET","path":"/api/tracking-domains/monitoring","scope":"mailing:read","summary":"Get tracking domain monitoring overview with click/send stats"},{"id":"TrackingDomainController_reportSpam","method":"POST","path":"/api/tracking-domains/{id}/report-spam","summary":"Report spam for a tracking domain (auto-pause at threshold)"},{"id":"RedirectSourceController_findAll","method":"GET","path":"/api/redirect-sources","summary":"List redirect sources"},{"id":"RedirectSourceController_create","method":"POST","path":"/api/redirect-sources","summary":"Create a redirect source"},{"id":"RedirectSourceController_getStats","method":"GET","path":"/api/redirect-sources/stats","scope":"mailing:read","summary":"Get redirect source statistics"},{"id":"RedirectSourceController_findOne","method":"GET","path":"/api/redirect-sources/{id}","summary":"Get a redirect source by id"},{"id":"RedirectSourceController_update","method":"PUT","path":"/api/redirect-sources/{id}","summary":"Update a redirect source"},{"id":"RedirectSourceController_remove","method":"DELETE","path":"/api/redirect-sources/{id}","summary":"Delete a redirect source"},{"id":"BotListController_stats","method":"GET","path":"/api/bot-list","summary":"Bot-list stats (feed count, custom CIDR/UA, last refresh). GLOBAL cross-tenant list for the cloaking redirect layer (#214 Ф3, SUPER-only): matched entries mark a click as a bot on cloakMode=bot_split links (→ botDecoyUrl). Changes here affect bot detection for ALL tenants."},{"id":"BotListController_refresh","method":"POST","path":"/api/bot-list/refresh","scope":"admin:write","summary":"Reload external bot-feeds now (BOT_FEED_URLS) into the in-memory matcher. SUPER-only, global. Gated by BOT_FEED_ENABLED + RUN_CRON_JOBS; normally refreshed on a schedule."},{"id":"BotListController_addCidr","method":"POST","path":"/api/bot-list/cidr","scope":"admin:write","summary":"Add a custom bot CIDR to the GLOBAL bot-list (e.g. 203.0.113.0/24). Clicks from these IPs on cloakMode=bot_split links are deflected to botDecoyUrl (+BOT_CLICK). SUPER-only; affects all tenants — use narrow ranges."},{"id":"BotListController_removeCidr","method":"DELETE","path":"/api/bot-list/cidr","scope":"admin:write","summary":"Remove a custom bot CIDR from the GLOBAL bot-list. SUPER-only."},{"id":"BotListController_addUa","method":"POST","path":"/api/bot-list/ua","scope":"admin:write","summary":"Add a custom bot User-Agent regex to the GLOBAL bot-list (e.g. MyScanner). UA match → bot → deflect to botDecoyUrl on cloakMode=bot_split links. SUPER-only; affects all tenants."},{"id":"BotListController_removeUa","method":"DELETE","path":"/api/bot-list/ua","scope":"admin:write","summary":"Remove a custom bot User-Agent regex from the GLOBAL bot-list. SUPER-only."},{"id":"admin.browser-queue","method":"GET","path":"/api/admin/browser-queue","scope":"admin:read","summary":"Get browser queue stats and fair-share view"},{"id":"BrowserQueueController_getJobs","method":"GET","path":"/api/admin/browser-queue/jobs","scope":"admin:read","summary":"List browser queue jobs by status with pagination"},{"id":"BrowserQueueController_cancelJob","method":"POST","path":"/api/admin/browser-queue/{id}/cancel","summary":"Cancel a browser queue job by id"},{"id":"BrowserQueueController_retryJob","method":"POST","path":"/api/admin/browser-queue/{id}/retry","summary":"Retry a failed browser queue job"},{"id":"admin.browser-queue.pause","method":"POST","path":"/api/admin/browser-queue/pause","scope":"admin:write","summary":"Pause the browser queue"},{"id":"BrowserQueueController_resume","method":"POST","path":"/api/admin/browser-queue/resume","scope":"admin:write","summary":"Resume the browser queue"},{"id":"ContentAnalyzerController_check","method":"POST","path":"/api/content-analyzer/check","scope":"mailing:read","summary":"Analyze email subject/body for spam triggers and return score 0..100"},{"id":"tasks.list","method":"GET","path":"/api/tasks","scope":"tasks:read","summary":"List tasks with pagination and status/method filters"},{"id":"tasks.create","method":"POST","path":"/api/tasks","scope":"tasks:write","summary":"Создать задание. СКОРИНГ САЙТОВ (лидген): methodId=22 + methodName=\"scoring\" + companyListId (items наполнятся из списка компаний при старте) → POST /tasks/:id/steps (SITE_AVAILABILITY, затем AI_CONTENT) → POST /tasks/:id/start. Другие methodId: 11=email-валидация, 14=ICP review, 15=DIG, 12=рассылка (legacy — предпочитай /campaigns)."},{"id":"TasksController_findById","method":"GET","path":"/api/tasks/{id}","summary":"Get a single task by ID"},{"id":"TasksController_update","method":"PATCH","path":"/api/tasks/{id}","summary":"Update task description, configuration, or schedule"},{"id":"TasksController_remove","method":"DELETE","path":"/api/tasks/{id}","summary":"Delete a task"},{"id":"TasksController_listBranches","method":"GET","path":"/api/tasks/{id}/branches","summary":"List sub-sequence branches of a task"},{"id":"TasksController_createBranch","method":"POST","path":"/api/tasks/{id}/branches","summary":"Create a sub-sequence branch off a task"},{"id":"TasksController_enrollInBranch","method":"POST","path":"/api/tasks/{id}/branches/{branchId}/enroll","summary":"Enroll contacts into a task branch"},{"id":"TasksController_getItems","method":"GET","path":"/api/tasks/{id}/items","summary":"List items processed by a task with pagination"},{"id":"TasksController_getItem","method":"GET","path":"/api/tasks/{id}/items/{itemId}","summary":"Get a single task item by ID"},{"id":"TasksController_getStats","method":"GET","path":"/api/tasks/{id}/stats","summary":"Get aggregate stats for a task"},{"id":"TasksController_getErrors","method":"GET","path":"/api/tasks/{id}/errors","summary":"List errors encountered during a task run"},{"id":"TasksController_start","method":"POST","path":"/api/tasks/{id}/start","summary":"Запустить (или возобновить) задание. Если items пусты — наполнит их из contactListId/companyListId задания. Прогресс: GET /tasks/:id (processedItems/totalItems); для скоринга: GET /tasks/:id/scoring-stats и /tasks/:id/scoring-results?status=ACTIVE (score, companyType, контакты с сайта)."},{"id":"TasksController_pause","method":"POST","path":"/api/tasks/{id}/pause","summary":"Pause a running task"},{"id":"TasksController_stop","method":"POST","path":"/api/tasks/{id}/stop","summary":"Stop a task (mark as DONE)"},{"id":"TasksController_restart","method":"POST","path":"/api/tasks/{id}/restart","summary":"Restart a completed or stopped task"},{"id":"TasksController_getAnalytics","method":"GET","path":"/api/tasks/{id}/analytics","summary":"Get analytics for a task (open/click/reply rates)"},{"id":"TasksController_getMonitor","method":"GET","path":"/api/tasks/{id}/monitor","summary":"Get real-time monitor data for a running task"},{"id":"TasksController_getReportCsv","method":"GET","path":"/api/tasks/{id}/report.csv","summary":"Download a CSV report of all task items"},{"id":"TasksController_getCircuitBreaker","method":"GET","path":"/api/tasks/{id}/circuit-breaker","summary":"Get the circuit-breaker state for a task"},{"id":"TasksController_resetCircuitBreaker","method":"POST","path":"/api/tasks/{id}/circuit-breaker/reset","summary":"Reset a tripped circuit breaker for a task"},{"id":"TasksController_getPipelineSteps","method":"GET","path":"/api/tasks/{id}/steps","summary":"List pipeline steps configured on a task"},{"id":"TasksController_addPipelineStep","method":"POST","path":"/api/tasks/{id}/steps","summary":"Добавить шаг пайплайна к заданию. Типы: SITE_AVAILABILITY, AI_CONTENT, KEYWORDS, EMAIL_EXTRACT, PHONE_EXTRACT, SOCIAL_LINKS, TECH_DETECT, GEO_FILTER, NALOG_LOOKUP и др. Для AI_CONTENT: config.messages=[{role:system,...},{role:user,...}] с плейсхолдерами {-Variable.page_text-}/{-Variable.domain-}, config.min_score (success при score>=min_score). Роутинг: onSuccess/onFail/onError = CONTINUE|STOP|MOVE_TO_LIST (+onSuccessTarget=id списка)|DELETE. Типовой скоринг: шаг1 SITE_AVAILABILITY (onFail=STOP), шаг2 AI_CONTENT (onSuccess=MOVE_TO_LIST в список целевых)."},{"id":"TasksController_reorderPipelineSteps","method":"PUT","path":"/api/tasks/{id}/steps/reorder","summary":"Reorder pipeline steps in a task"},{"id":"TasksController_updatePipelineStep","method":"PATCH","path":"/api/tasks/{id}/steps/{stepId}","summary":"Update a single pipeline step"},{"id":"TasksController_removePipelineStep","method":"DELETE","path":"/api/tasks/{id}/steps/{stepId}","summary":"Delete a pipeline step from a task"},{"id":"TasksController_getScoringResults","method":"GET","path":"/api/tasks/{id}/scoring-results","summary":"List scoring results for a task with pagination"},{"id":"TasksController_getScoringStats","method":"GET","path":"/api/tasks/{id}/scoring-stats","summary":"Get aggregate scoring statistics for a task"},{"id":"TasksController_deleteScoringResult","method":"DELETE","path":"/api/tasks/{id}/scoring-results/{resultId}","summary":"Delete a single scoring result"},{"id":"TasksController_retryScoringResults","method":"POST","path":"/api/tasks/{id}/scoring-results/retry","summary":"Retry failed scoring results for a task"},{"id":"TasksController_getScoringResultsCsv","method":"GET","path":"/api/tasks/{id}/scoring-results.csv","summary":"Download a CSV of scoring results"},{"id":"TasksController_getErrorSettings","method":"GET","path":"/api/tasks/{id}/error-settings","summary":"Get the error-handling settings for a task"},{"id":"TasksController_updateErrorSettings","method":"PATCH","path":"/api/tasks/{id}/error-settings","summary":"Update error-handling settings for a task"},{"id":"TasksController_getMemory","method":"GET","path":"/api/tasks/{id}/memory","summary":"Get AI memory instructions for a task"},{"id":"TasksController_updateMemory","method":"PATCH","path":"/api/tasks/{id}/memory","summary":"Update AI memory instructions for a task"},{"id":"TasksController_getAiSettings","method":"GET","path":"/api/tasks/{id}/ai-settings","summary":"Get the AI provider/model settings for a task"},{"id":"TasksController_updateAiSettings","method":"PATCH","path":"/api/tasks/{id}/ai-settings","summary":"Update the AI provider/model settings for a task"},{"id":"TasksController_getCronSettings","method":"GET","path":"/api/tasks/{id}/cron","summary":"Get the cron scheduling settings for a task"},{"id":"TasksController_updateCronSettings","method":"PATCH","path":"/api/tasks/{id}/cron","summary":"Update the cron scheduling settings for a task"},{"id":"TasksController_triggerCron","method":"POST","path":"/api/tasks/{id}/cron/trigger","summary":"Manually trigger a task cron run"},{"id":"creatives.list","method":"GET","path":"/api/creatives","scope":"creatives:read","summary":"List creatives with pagination and search"},{"id":"creatives.create","method":"POST","path":"/api/creatives","scope":"creatives:write","summary":"Create a new creative"},{"id":"CreativesController_aiGenerate","method":"POST","path":"/api/creatives/ai-generate","scope":"creatives:write","summary":"Generate a creative draft via AI"},{"id":"CreativesController_createAutopilotV2","method":"POST","path":"/api/creatives/autopilot-v2","scope":"creatives:write","summary":"Create a new Autopilot v2 creative"},{"id":"CreativesController_pdfStatus","method":"GET","path":"/api/creatives/pdf-status","scope":"creatives:read","summary":"Get the PDF generation queue status"},{"id":"CreativesController_servePdf","method":"GET","path":"/api/creatives/pdf/{filename}","summary":"Download a generated PDF by filename"},{"id":"CreativesController_getAvailableVariables","method":"GET","path":"/api/creatives/variables/available","scope":"creatives:read","summary":"List available template variables"},{"id":"CreativesController_findById","method":"GET","path":"/api/creatives/{id}","summary":"Get a single creative by ID"},{"id":"CreativesController_update","method":"PATCH","path":"/api/creatives/{id}","summary":"Update a creative"},{"id":"CreativesController_remove","method":"DELETE","path":"/api/creatives/{id}","summary":"Delete a creative"},{"id":"CreativesController_getStats","method":"GET","path":"/api/creatives/{id}/stats","summary":"Get stats for a creative"},{"id":"CreativesController_preview","method":"POST","path":"/api/creatives/{id}/preview","summary":"Render a preview of a creative for a sample contact"},{"id":"CreativesController_startInboxPlacementTest","method":"POST","path":"/api/creatives/{id}/inbox-placement-test","summary":"Start an inbox placement test for a creative"},{"id":"CreativesController_getInboxPlacementTest","method":"GET","path":"/api/creatives/{id}/inbox-placement-test/{token}","summary":"Get the result of an inbox placement test"},{"id":"CreativesController_getVariables","method":"GET","path":"/api/creatives/{id}/variables","summary":"Get template variables used in a creative"},{"id":"CreativesController_analyzeSpintax","method":"GET","path":"/api/creatives/{id}/spintax","summary":"Analyze spintax patterns in a creative"},{"id":"CreativesController_duplicate","method":"POST","path":"/api/creatives/{id}/copy","summary":"Duplicate a creative"},{"id":"CreativesController_getVersions","method":"GET","path":"/api/creatives/{id}/versions","summary":"List versions of a creative"},{"id":"CreativesController_createVersion","method":"POST","path":"/api/creatives/{id}/versions","summary":"Create a new version of a creative"},{"id":"CreativesController_restoreVersion","method":"POST","path":"/api/creatives/{id}/versions/{versionId}/restore","summary":"Restore a creative to a prior version"},{"id":"CreativesController_getTestSends","method":"GET","path":"/api/creatives/{id}/test-sends","summary":"List test sends of a creative"},{"id":"CreativesController_createTestSend","method":"POST","path":"/api/creatives/{id}/test-send","summary":"Send a test email of a creative"},{"id":"CreativesController_autopilotGeneratePrompt","method":"POST","path":"/api/creatives/{id}/autopilot/generate-prompt","summary":"Generate an Autopilot meta-prompt for a creative"},{"id":"CreativesController_autopilotGeneratePromptV2","method":"POST","path":"/api/creatives/{id}/autopilot/v2/generate-prompt","summary":"Generate an Autopilot v2 meta-prompt"},{"id":"CreativesController_bankV2Generate","method":"POST","path":"/api/creatives/{id}/rules/bank/generate","summary":"Enqueue a bank-generation job for a creative"},{"id":"CreativesController_bankGenGet","method":"GET","path":"/api/creatives/{id}/rules/bank/jobs/{jobId}","summary":"Get the status of a bank-generation job"},{"id":"CreativesController_bankGenList","method":"GET","path":"/api/creatives/{id}/rules/bank/jobs","summary":"List bank-generation jobs for a creative"},{"id":"CreativesController_bankGenCancel","method":"POST","path":"/api/creatives/{id}/rules/bank/jobs/{jobId}/cancel","summary":"Cancel a bank-generation job"},{"id":"CreativesController_bankV2Edit","method":"PATCH","path":"/api/creatives/{id}/rules/bank/{tid}","summary":"Update a single bank template (rules v2)"},{"id":"CreativesController_bankV2Action","method":"POST","path":"/api/creatives/{id}/rules/bank/{tid}/action","summary":"Run an action on a bank template (approve/reject/etc.)"},{"id":"CreativesController_autopilotPreviewMetaPrompt","method":"POST","path":"/api/creatives/{id}/autopilot/preview-meta-prompt","summary":"Preview the meta-prompt for a creative"},{"id":"CreativesController_autopilotSegmentMetaPrompt","method":"PATCH","path":"/api/creatives/{id}/autopilot/segment/{segmentId}/meta-prompt","summary":"Update the meta-prompt of a segment"},{"id":"CreativesController_autopilotTestBatch","method":"POST","path":"/api/creatives/{id}/autopilot/test-batch","summary":"Run a test batch through Autopilot"},{"id":"CreativesController_bankGenerate","method":"POST","path":"/api/creatives/{id}/autopilot/bank/generate","summary":"Trigger Autopilot bank generation"},{"id":"CreativesController_bankPipelineStatus","method":"GET","path":"/api/creatives/{id}/autopilot/bank/pipeline/{jobId}","summary":"Get the status of an Autopilot bank pipeline job"},{"id":"CreativesController_bankGet","method":"GET","path":"/api/creatives/{id}/autopilot/bank","summary":"List Autopilot bank templates"},{"id":"CreativesController_bankTemplateAction","method":"PATCH","path":"/api/creatives/{id}/autopilot/bank/templates/{templateId}","summary":"Update an Autopilot bank template"},{"id":"CreativesController_bankDeleteTemplate","method":"DELETE","path":"/api/creatives/{id}/autopilot/bank/templates/{templateId}","summary":"Delete a single Autopilot bank template"},{"id":"CreativesController_bankGetTemplate","method":"GET","path":"/api/creatives/{id}/autopilot/bank/templates/{templateId}","summary":"Get a single Autopilot bank template"},{"id":"CreativesController_bankApproveAll","method":"POST","path":"/api/creatives/{id}/autopilot/bank/approve-all","summary":"Approve all pending Autopilot bank templates"},{"id":"CreativesController_bankDeleteAll","method":"DELETE","path":"/api/creatives/{id}/autopilot/bank/templates","summary":"Delete all Autopilot bank templates"},{"id":"CreativesController_bankCreateTemplate","method":"POST","path":"/api/creatives/{id}/autopilot/bank/templates","summary":"Create a new Autopilot bank template"},{"id":"CreativesController_bankRegenerate","method":"POST","path":"/api/creatives/{id}/autopilot/bank/regenerate","summary":"Regenerate Autopilot bank templates"},{"id":"CreativesController_bankUpdateConfig","method":"PATCH","path":"/api/creatives/{id}/autopilot/bank/config","summary":"Update Autopilot bank configuration"},{"id":"CreativesController_bankPreview","method":"POST","path":"/api/creatives/{id}/autopilot/bank/preview","summary":"Preview Autopilot bank output"},{"id":"CreativesController_bankPreviewWithQc","method":"POST","path":"/api/creatives/{id}/autopilot/bank/preview-with-qc","summary":"Preview Autopilot bank output with QC checks"},{"id":"CreativesController_bankUsage","method":"GET","path":"/api/creatives/{id}/autopilot/bank/usage","summary":"Get Autopilot bank usage stats"},{"id":"CreativesController_generateForContact","method":"POST","path":"/api/creatives/{id}/generate-for-contact","summary":"Generate a creative for a specific contact"},{"id":"CreativesController_autopilotDashboard","method":"GET","path":"/api/creatives/{id}/autopilot/dashboard","summary":"Get the Autopilot dashboard for a creative"},{"id":"CreativesController_backfillTier2","method":"POST","path":"/api/creatives/{id}/autopilot/dashboard/backfill-t2","summary":"Backfill Tier-2 QC results on the Autopilot dashboard"},{"id":"CreativesController_auditorGet","method":"GET","path":"/api/creatives/{id}/autopilot/auditor","summary":"Get the Autopilot auditor configuration"},{"id":"CreativesController_auditorUpdate","method":"PATCH","path":"/api/creatives/{id}/autopilot/auditor","summary":"Update the Autopilot auditor configuration"},{"id":"CreativesController_auditorStart","method":"POST","path":"/api/creatives/{id}/autopilot/auditor/start","summary":"Start the Autopilot auditor"},{"id":"CreativesController_auditorPause","method":"POST","path":"/api/creatives/{id}/autopilot/auditor/pause","summary":"Pause the Autopilot auditor"},{"id":"CreativesController_auditorStop","method":"POST","path":"/api/creatives/{id}/autopilot/auditor/stop","summary":"Stop the Autopilot auditor"},{"id":"CreativesController_auditorRun","method":"POST","path":"/api/creatives/{id}/autopilot/auditor/run","summary":"Run the Autopilot auditor once"},{"id":"CreativesController_auditorLogs","method":"GET","path":"/api/creatives/{id}/autopilot/auditor/logs","summary":"Get logs for the Autopilot auditor"},{"id":"CreativesController_auditorClearLogs","method":"DELETE","path":"/api/creatives/{id}/autopilot/auditor/logs","summary":"Clear logs for the Autopilot auditor"},{"id":"CreativesController_checklistGet","method":"GET","path":"/api/creatives/{id}/autopilot/checklist","summary":"Get the Autopilot launch checklist"},{"id":"CreativesController_checklistSandbox","method":"POST","path":"/api/creatives/{id}/autopilot/checklist/sandbox","summary":"Run the sandbox step of the Autopilot checklist"},{"id":"CreativesController_checklistQC","method":"POST","path":"/api/creatives/{id}/autopilot/checklist/qc","summary":"Run the QC step of the Autopilot checklist"},{"id":"CreativesController_checklistTestSend","method":"POST","path":"/api/creatives/{id}/autopilot/checklist/test-send","summary":"Run the test-send step of the Autopilot checklist"},{"id":"CreativesController_checklistCostEstimate","method":"POST","path":"/api/creatives/{id}/autopilot/checklist/cost-estimate","summary":"Estimate cost for the Autopilot launch"},{"id":"CreativesController_checklistLock","method":"POST","path":"/api/creatives/{id}/autopilot/checklist/lock","summary":"Lock the Autopilot checklist before launch"},{"id":"CreativesController_checklistUnlock","method":"POST","path":"/api/creatives/{id}/autopilot/checklist/unlock","summary":"Unlock the Autopilot checklist"},{"id":"CreativesController_qcConfig","method":"GET","path":"/api/creatives/{id}/autopilot/qc/config","summary":"Get the Autopilot QC configuration"},{"id":"CreativesController_qcUpdateRules","method":"PATCH","path":"/api/creatives/{id}/autopilot/qc/rules","summary":"Update Autopilot QC Tier-1 rules"},{"id":"CreativesController_qcUpdateTier2","method":"PATCH","path":"/api/creatives/{id}/autopilot/qc/tier2","summary":"Update Autopilot QC Tier-2 configuration"},{"id":"CreativesController_qcTest","method":"POST","path":"/api/creatives/{id}/autopilot/qc/test","summary":"Run a QC test on sample content"},{"id":"CreativesController_sandboxRunObservable","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/run-observable","summary":"Start an observable Autopilot sandbox run"},{"id":"CreativesController_sandboxObservableStatus","method":"GET","path":"/api/creatives/{id}/autopilot/sandbox/observable-status","summary":"Get the status of an observable sandbox run"},{"id":"CreativesController_sandboxCancelObservable","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/cancel-observable","summary":"Cancel an observable sandbox run"},{"id":"CreativesController_sandboxClearObservable","method":"DELETE","path":"/api/creatives/{id}/autopilot/sandbox/observable","summary":"Delete the observable sandbox state"},{"id":"CreativesController_sandboxRun","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/run","summary":"Run the Autopilot sandbox pipeline"},{"id":"CreativesController_sandboxAvailableVars","method":"GET","path":"/api/creatives/{id}/autopilot/sandbox/available-vars","summary":"List variables available to the sandbox"},{"id":"CreativesController_variableValues","method":"GET","path":"/api/creatives/{id}/autopilot/variable-values","summary":"Get computed variable values for a creative"},{"id":"CreativesController_segmentCount","method":"POST","path":"/api/creatives/{id}/autopilot/segment-count","summary":"Count contacts matching a sandbox segment"},{"id":"CreativesController_allFieldDefinitions","method":"GET","path":"/api/creatives/{id}/autopilot/all-field-definitions","summary":"Get all field definitions available to Autopilot"},{"id":"CreativesController_sandboxMatchContacts","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/match-contacts","summary":"Match contacts against a sandbox segment definition"},{"id":"CreativesController_sandboxTestSelection","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/test-selection","summary":"Run a test selection against the sandbox"},{"id":"CreativesController_sandboxGetTestSelection","method":"GET","path":"/api/creatives/{id}/autopilot/sandbox/test-selection","summary":"Get the cached test selection result"},{"id":"CreativesController_sandboxHistory","method":"GET","path":"/api/creatives/{id}/autopilot/sandbox/history","summary":"Get the sandbox run history"},{"id":"CreativesController_sandboxHistoryClearAll","method":"DELETE","path":"/api/creatives/{id}/autopilot/sandbox/history","summary":"Clear the sandbox run history"},{"id":"CreativesController_sandboxHistoryDeleteOne","method":"DELETE","path":"/api/creatives/{id}/autopilot/sandbox/history/{idx}","summary":"Delete one entry from the sandbox history"},{"id":"CreativesController_sandboxStatus","method":"GET","path":"/api/creatives/{id}/autopilot/sandbox/status","summary":"Get the current sandbox status"},{"id":"CreativesController_sandboxCancel","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/cancel","summary":"Cancel a running sandbox run"},{"id":"CreativesController_sandboxApply","method":"POST","path":"/api/creatives/{id}/autopilot/sandbox/apply","summary":"Apply the sandbox result to the creative"},{"id":"CreativesController_saveVariableRules","method":"PATCH","path":"/api/creatives/{id}/autopilot/variable-rules","summary":"Update the Autopilot variable rules"},{"id":"CreativesController_getVariableRules","method":"GET","path":"/api/creatives/{id}/autopilot/variable-rules","summary":"Get the Autopilot variable rules"},{"id":"CreativesController_previewVariableRules","method":"POST","path":"/api/creatives/{id}/autopilot/variable-rules/preview","summary":"Preview the effect of variable rules"},{"id":"CreativesController_runPipeline","method":"POST","path":"/api/creatives/{id}/autopilot/pipeline/run","summary":"Run the full Autopilot generation pipeline"},{"id":"CreativesController_generatePdf","method":"POST","path":"/api/creatives/{id}/generate-pdf","summary":"Generate a PDF from a creative"},{"id":"CreativesController_getMetaPromptBaseV2","method":"GET","path":"/api/creatives/{id}/autopilot/v2/meta-prompt-base","summary":"Get the base meta-prompt for Autopilot v2"},{"id":"CreativesController_getMetaPrompt","method":"GET","path":"/api/creatives/{id}/autopilot/meta-prompt","summary":"Get the meta-prompt for a creative"},{"id":"CreativesController_putMetaPrompt","method":"PUT","path":"/api/creatives/{id}/autopilot/meta-prompt","summary":"Replace the meta-prompt for a creative"},{"id":"CreativesController_deleteMetaPrompt","method":"DELETE","path":"/api/creatives/{id}/autopilot/meta-prompt","summary":"Delete the meta-prompt of a creative"},{"id":"CreativesController_bankGetTemplateStats","method":"GET","path":"/api/creatives/{id}/autopilot/bank/templates/{templateId}/stats","summary":"Get stats for a single Autopilot bank template"},{"id":"CreativesController_bankGenerateOneTemplate","method":"POST","path":"/api/creatives/{id}/autopilot/bank/templates/generate-one","summary":"Generate a single Autopilot bank template"},{"id":"CreativesController_bankUpdateTemplateContent","method":"PUT","path":"/api/creatives/{id}/autopilot/bank/templates/{templateId}/content","summary":"Replace the content of a bank template"},{"id":"EmailAccountsController_lookupProvider","method":"GET","path":"/api/email-accounts/lookup","scope":"accounts:read","summary":"Look up provider SMTP/IMAP settings for an email address"},{"id":"EmailAccountsController_testUnsaved","method":"POST","path":"/api/email-accounts/test-unsaved","scope":"accounts:write","summary":"Test SMTP/IMAP credentials without saving the account"},{"id":"accounts.list","method":"GET","path":"/api/email-accounts","scope":"accounts:read","summary":"List email accounts with filters and pagination"},{"id":"accounts.create","method":"POST","path":"/api/email-accounts","scope":"accounts:write","summary":"Create a new email account. Pass `email` only — SMTP/IMAP/service are auto-detected via GET /email-accounts/lookup. Override host/port/credentials explicitly for custom domains. The legacy `provider` field is normalized to the `service` enum (no separate column)."},{"id":"EmailAccountsController_getStats","method":"GET","path":"/api/email-accounts/stats","scope":"accounts:read","summary":"Get aggregated stats across all email accounts"},{"id":"EmailAccountsController_checkDuplicate","method":"GET","path":"/api/email-accounts/check-duplicate","scope":"accounts:read","summary":"Check if an email address is already registered"},{"id":"EmailAccountsController_getAccountStats","method":"GET","path":"/api/email-accounts/{id}/stats","summary":"Get per-account email statistics"},{"id":"EmailAccountsController_findById","method":"GET","path":"/api/email-accounts/{id}","summary":"Get an email account by id"},{"id":"EmailAccountsController_update","method":"PATCH","path":"/api/email-accounts/{id}","summary":"Update an email account"},{"id":"EmailAccountsController_remove","method":"DELETE","path":"/api/email-accounts/{id}","summary":"Delete an email account"},{"id":"EmailAccountsController_fetchImap","method":"POST","path":"/api/email-accounts/{id}/fetch-imap","summary":"Trigger an IMAP fetch for an account (queue or fast-lane)"},{"id":"EmailAccountsController_testConnection","method":"POST","path":"/api/email-accounts/{id}/test","summary":"Test SMTP and/or IMAP connectivity for an account"},{"id":"EmailAccountsController_testReceive","method":"POST","path":"/api/email-accounts/{id}/test-receive","summary":"Universal Receive Test (#4). Probes the real receive transport for this account — Microsoft Graph, Gmail API (planned), IMAP direct, IMAP via Agent, or GAS WebApp — and returns a single honest result with transport label, per-step log, and (when available) inbox counts. Rate-limited per account (1 per 5s)."},{"id":"EmailAccountsController_testSend","method":"POST","path":"/api/email-accounts/{id}/test-send","summary":"Universal Send Test (#5). Dry-run probe of the real send transport — Microsoft Graph sendMail (planned), Gmail API drafts (planned), SMTP XOAUTH2 verify (planned), SMTP password, SMTP via Agent, or GAS WebApp health (planned). Never sends a real message. Rate-limited per account (1 per 5s)."},{"id":"EmailAccountsController_checkDns","method":"GET","path":"/api/email-accounts/{id}/dns-check","summary":"Run DNS health check for the account domain"},{"id":"EmailAccountsController_resetCounters","method":"POST","path":"/api/email-accounts/{id}/reset-counters","summary":"Reset daily send counters for an account"},{"id":"EmailAccountsController_warmupStart","method":"POST","path":"/api/email-accounts/{id}/warmup/start","summary":"Start mailbox warm-up for an account"},{"id":"EmailAccountsController_warmupStop","method":"POST","path":"/api/email-accounts/{id}/warmup/stop","summary":"Stop mailbox warm-up for an account"},{"id":"EmailAccountsController_warmupStats","method":"GET","path":"/api/email-accounts/{id}/warmup","summary":"Get mailbox warm-up stats for an account"},{"id":"EmailAccountsController_warmupConfigure","method":"PATCH","path":"/api/email-accounts/{id}/warmup","summary":"Configure mailbox warm-up parameters"},{"id":"EmailAccountsController_suspend","method":"POST","path":"/api/email-accounts/{id}/suspend","summary":"Suspend an email account"},{"id":"EmailAccountsController_unsuspend","method":"POST","path":"/api/email-accounts/{id}/unsuspend","summary":"Unsuspend an email account"},{"id":"EmailAccountsController_updateWorkStatus","method":"PATCH","path":"/api/email-accounts/{id}/work-status","summary":"Update the work status (IDLE / IN_PROGRESS) of an account"},{"id":"EmailAccountsController_gasSetup","method":"POST","path":"/api/email-accounts/{id}/gas/setup","summary":"Generate GAS setup instructions for the account"},{"id":"EmailAccountsController_gasVerify","method":"POST","path":"/api/email-accounts/{id}/gas/verify","summary":"Verify a deployed GAS web app URL for the account"},{"id":"EmailAccountsController_gasPing","method":"POST","path":"/api/email-accounts/{id}/gas/ping","summary":"Ping the GAS web app to verify connectivity"},{"id":"EmailAccountsController_gasTestSend","method":"POST","path":"/api/email-accounts/{id}/gas/test-send","summary":"Send a test email via GAS"},{"id":"EmailAccountsController_gasTestFetch","method":"POST","path":"/api/email-accounts/{id}/gas/test-fetch","summary":"Run a test fetch via GAS"},{"id":"EmailAccountsController_gasDisable","method":"PATCH","path":"/api/email-accounts/{id}/gas/disable","summary":"Disable GAS integration for an account"},{"id":"EmailAccountsController_gasLabels","method":"GET","path":"/api/email-accounts/{id}/gas/labels","summary":"List Gmail labels available via GAS"},{"id":"EmailAccountsController_findAllLists","method":"GET","path":"/api/email-account-lists","scope":"accounts:read","summary":"List email account lists"},{"id":"EmailAccountsController_createList","method":"POST","path":"/api/email-account-lists","scope":"accounts:write","summary":"Create an email account list"},{"id":"EmailAccountsController_updateList","method":"PATCH","path":"/api/email-account-lists/{id}","summary":"Update an email account list"},{"id":"EmailAccountsController_removeList","method":"DELETE","path":"/api/email-account-lists/{id}","summary":"Delete an email account list"},{"id":"EmailAccountsController_relayHealth","method":"GET","path":"/api/email-account-lists/{id}/relay-health","summary":"Relay pool health (#40): live eligibility per account, next relay, starving flag, recent dispatches and sticky bindings"},{"id":"GasWebhookController_handleWebhook","method":"POST","path":"/api/gas/webhook","summary":"Receive a GAS push notification and trigger IMAP fetch"},{"id":"InboxIngestController_mailArrived","method":"POST","path":"/api/internal/mail-arrived","summary":"Internal: notify that new mail arrived and trigger immediate IMAP fetch"},{"id":"imap.stats","method":"GET","path":"/api/imap-orchestrator/stats","scope":"imap:read","summary":"Get IMAP orchestrator dashboard stats"},{"id":"ImapOrchestratorController_getJobs","method":"GET","path":"/api/imap-orchestrator/jobs","scope":"imap:read","summary":"List recent IMAP orchestrator jobs"},{"id":"ImapOrchestratorController_fetchAccount","method":"POST","path":"/api/imap-orchestrator/fetch/{accountId}","summary":"Manually trigger an IMAP fetch for a specific account"},{"id":"ImapOrchestratorController_getAttention","method":"GET","path":"/api/imap-orchestrator/attention","scope":"imap:read","summary":"List email accounts needing manual intervention"},{"id":"imap.heal","method":"POST","path":"/api/imap-orchestrator/heal","scope":"imap:write","summary":"Auto-heal stuck GAS accounts and IMAP locks for the current tenant"},{"id":"ImapOrchestratorController_healAll","method":"POST","path":"/api/imap-orchestrator/heal-all","scope":"imap:write","summary":"Auto-heal stuck IMAP/GAS state across all tenants"},{"id":"imap.fetch-all","method":"POST","path":"/api/imap-orchestrator/fetch-all","scope":"imap:write","summary":"Trigger an IMAP fetch for every active account in the tenant"},{"id":"imap.tech-log","method":"GET","path":"/api/imap-orchestrator/tech-log","scope":"imap:read","summary":"Get the latest N IMAP job log entries for monitoring"},{"id":"ImapOrchestratorController_getRecentDialogs","method":"GET","path":"/api/imap-orchestrator/recent-dialogs","scope":"imap:read","summary":"List recently inserted inbound dialogs"},{"id":"ImapOrchestratorController_cancelJob","method":"DELETE","path":"/api/imap-orchestrator/jobs/{id}","summary":"Cancel an IMAP orchestrator job"},{"id":"ImapOrchestratorController_getOverrides","method":"GET","path":"/api/imap-orchestrator/marking-overrides","scope":"imap:read","summary":"List dialog marking override rules"},{"id":"ImapOrchestratorController_createOverride","method":"POST","path":"/api/imap-orchestrator/marking-overrides","scope":"imap:write","summary":"Create a dialog marking override rule"},{"id":"ImapOrchestratorController_updateOverride","method":"POST","path":"/api/imap-orchestrator/marking-overrides/{id}","summary":"Update a dialog marking override rule"},{"id":"ImapOrchestratorController_deleteOverride","method":"DELETE","path":"/api/imap-orchestrator/marking-overrides/{id}","summary":"Delete a dialog marking override rule"},{"id":"ImapOrchestratorController_getPatterns","method":"GET","path":"/api/imap-orchestrator/marking-patterns","scope":"imap:read","summary":"List dialog marking regex patterns"},{"id":"ImapOrchestratorController_createPattern","method":"POST","path":"/api/imap-orchestrator/marking-patterns","scope":"imap:write","summary":"Create a dialog marking regex pattern"},{"id":"ImapOrchestratorController_updatePattern","method":"POST","path":"/api/imap-orchestrator/marking-patterns/{id}","summary":"Update a dialog marking regex pattern"},{"id":"ImapOrchestratorController_deletePattern","method":"DELETE","path":"/api/imap-orchestrator/marking-patterns/{id}","summary":"Delete a dialog marking regex pattern"},{"id":"ImapOrchestratorController_getHealthAccounts","method":"GET","path":"/api/imap-orchestrator/health-accounts","scope":"imap:read","summary":"Admin: list all email accounts across every tenant for health checks"},{"id":"ImapOrchestratorController_healthTest","method":"POST","path":"/api/imap-orchestrator/health-test","scope":"imap:write","summary":"Admin: run SMTP/IMAP connection test (or round-trip) for a specific account"},{"id":"ImapOrchestratorController_killImapCron","method":"POST","path":"/api/imap-orchestrator/admin/kill","scope":"admin:write","summary":"Emergency stop for IMAP cron triggers (#6 Layer 4). All enqueueAll cycles short-circuit until /resume is called. Idempotent — repeated calls only update the reason field."},{"id":"ImapOrchestratorController_resumeImapCron","method":"POST","path":"/api/imap-orchestrator/admin/resume","scope":"admin:write","summary":"Resume IMAP cron after a kill (#6 Layer 4)."},{"id":"ImapOrchestratorController_getImapHealth","method":"GET","path":"/api/imap-orchestrator/admin/health","scope":"admin:read","summary":"IMAP orchestrator kill-switch state + queue counts (#6 Layer 4). Returns whether the cron is currently paused and why."},{"id":"inbound-rules.list","method":"GET","path":"/api/inbound-rules","scope":"rules:read","summary":"List all inbound rules"},{"id":"inbound-rules.create","method":"POST","path":"/api/inbound-rules","scope":"rules:write","summary":"Create a new inbound rule"},{"id":"InboundRulesController_listAutomationEvents","method":"GET","path":"/api/inbound-rules/events","scope":"rules:read","summary":"List recent inbound-rule automation events"},{"id":"InboundRulesController_findById","method":"GET","path":"/api/inbound-rules/{id}","summary":"Get an inbound rule by id"},{"id":"InboundRulesController_update","method":"PATCH","path":"/api/inbound-rules/{id}","summary":"Update an inbound rule"},{"id":"InboundRulesController_delete","method":"DELETE","path":"/api/inbound-rules/{id}","summary":"Delete an inbound rule"},{"id":"InboundRulesController_reorder","method":"PATCH","path":"/api/inbound-rules/reorder","scope":"rules:write","summary":"Reorder inbound rules (sortOrder)"},{"id":"InboundRulesController_toggle","method":"PATCH","path":"/api/inbound-rules/{id}/toggle","summary":"Toggle the active flag of an inbound rule"},{"id":"InboundRulesController_testRules","method":"POST","path":"/api/inbound-rules/test","scope":"rules:read","summary":"Dry-run synthetic inbound message against active rules"},{"id":"InboundRulesController_reapply","method":"POST","path":"/api/inbound-rules/reapply","scope":"rules:write","summary":"Re-apply keyword routing to leads in the intake stage"},{"id":"DialogLinkerController_relink","method":"POST","path":"/api/dialog-linker/relink/{dialogId}","summary":"Manually re-run linker for a specific dialog"},{"id":"DialogLinkerController_backfill","method":"POST","path":"/api/dialog-linker/backfill","scope":"linker:write","summary":"Run dialog linker backfill across the tenant (admin)"},{"id":"linker.stats","method":"GET","path":"/api/dialog-linker/stats","scope":"linker:read","summary":"Get linker statistics by status"},{"id":"DialogLinkerController_getLogs","method":"GET","path":"/api/dialog-linker/logs/{dialogId}","summary":"Get linker logs for a specific dialog"},{"id":"linker.logs","method":"GET","path":"/api/dialog-linker/logs","scope":"linker:read","summary":"Get all linker logs (admin tech log)"},{"id":"MailRoutingController_findAll","method":"GET","path":"/api/mail-routing-rules","summary":"List all mail routing rules"},{"id":"MailRoutingController_create","method":"POST","path":"/api/mail-routing-rules","summary":"Create a new mail routing rule"},{"id":"MailRoutingController_findById","method":"GET","path":"/api/mail-routing-rules/{id}","summary":"Get a mail routing rule by id"},{"id":"MailRoutingController_update","method":"PATCH","path":"/api/mail-routing-rules/{id}","summary":"Update a mail routing rule"},{"id":"MailRoutingController_delete","method":"DELETE","path":"/api/mail-routing-rules/{id}","summary":"Delete a mail routing rule"},{"id":"MailRoutingController_toggle","method":"PATCH","path":"/api/mail-routing-rules/{id}/toggle","summary":"Toggle the active flag of a mail routing rule"},{"id":"MailRoutingController_testRules","method":"POST","path":"/api/mail-routing-rules/test","scope":"rules:read","summary":"Dry-run a synthetic email against active routing rules"},{"id":"customfields.list","method":"GET","path":"/api/custom-fields","scope":"customfields:read","summary":"List custom field definitions, optionally filtered by entity"},{"id":"customfields.create","method":"POST","path":"/api/custom-fields","scope":"customfields:write","summary":"Create a custom field definition"},{"id":"CustomFieldsController_update","method":"PATCH","path":"/api/custom-fields/{id}","summary":"Update a custom field definition"},{"id":"CustomFieldsController_remove","method":"DELETE","path":"/api/custom-fields/{id}","summary":"Delete a custom field definition"},{"id":"CustomFieldsController_reorder","method":"POST","path":"/api/custom-fields/reorder","scope":"customfields:write","summary":"Reorder custom field definitions"},{"id":"CustomFieldsController_getValues","method":"GET","path":"/api/custom-fields/values/{entity}/{entityId}","summary":"Get all custom field values for an entity instance"},{"id":"CustomFieldsController_setValue","method":"POST","path":"/api/custom-fields/values/{entity}/{entityId}","summary":"Set a custom field value for an entity instance"},{"id":"CustomFieldsController_bulkSetParams","method":"POST","path":"/api/custom-fields/params/{entity}/{entityId}","summary":"Legacy bulk set of params as key-value pairs"},{"id":"CustomFieldsController_getParams","method":"GET","path":"/api/custom-fields/params/{entity}/{entityId}","summary":"Legacy get of params as flat key-value object"},{"id":"views.list","method":"GET","path":"/api/saved-views","scope":"views:read","summary":"List saved views for an entity for the current user"},{"id":"views.create","method":"POST","path":"/api/saved-views","scope":"views:write","summary":"Create a saved view"},{"id":"SavedViewsController_update","method":"PATCH","path":"/api/saved-views/{id}","summary":"Update a saved view"},{"id":"SavedViewsController_remove","method":"DELETE","path":"/api/saved-views/{id}","summary":"Delete a saved view"},{"id":"ProjectTemplatesController_findRun","method":"GET","path":"/api/project-templates/runs/{runId}","summary":"Get a project run with steps and totals"},{"id":"ProjectTemplatesController_updateRun","method":"PATCH","path":"/api/project-templates/runs/{runId}","summary":"Update a project run (name, status, isTest, notes)"},{"id":"ProjectTemplatesController_removeRun","method":"DELETE","path":"/api/project-templates/runs/{runId}","summary":"Delete a project run"},{"id":"ProjectTemplatesController_updateRunStep","method":"PATCH","path":"/api/project-templates/runs/{runId}/steps/{stepId}","summary":"Update a run step (fact, status, issues/questions/ideas)"},{"id":"ProjectTemplatesController_findAll","method":"GET","path":"/api/project-templates","summary":"List project templates"},{"id":"ProjectTemplatesController_create","method":"POST","path":"/api/project-templates","summary":"Create a project template"},{"id":"ProjectTemplatesController_findOne","method":"GET","path":"/api/project-templates/{id}","summary":"Get a template with steps and runs"},{"id":"ProjectTemplatesController_update","method":"PATCH","path":"/api/project-templates/{id}","summary":"Update a template (name, description, isArchived)"},{"id":"ProjectTemplatesController_remove","method":"DELETE","path":"/api/project-templates/{id}","summary":"Delete a template (409 if it has runs — archive instead)"},{"id":"ProjectTemplatesController_addStep","method":"POST","path":"/api/project-templates/{id}/steps","summary":"Add a step to a template"},{"id":"ProjectTemplatesController_updateStep","method":"PATCH","path":"/api/project-templates/{id}/steps/{stepId}","summary":"Update a template step"},{"id":"ProjectTemplatesController_removeStep","method":"DELETE","path":"/api/project-templates/{id}/steps/{stepId}","summary":"Delete a template step"},{"id":"ProjectTemplatesController_reorder","method":"POST","path":"/api/project-templates/{id}/steps/reorder","summary":"Reorder template steps (full ordered id list)"},{"id":"ProjectTemplatesController_briefQuestions","method":"GET","path":"/api/project-templates/{id}/brief-questions","summary":"All brief questions of a template as one list"},{"id":"ProjectTemplatesController_summary","method":"GET","path":"/api/project-templates/{id}/summary","summary":"Plan vs avg fact per step over DONE runs (scope: all|test|real)"},{"id":"ProjectTemplatesController_createRun","method":"POST","path":"/api/project-templates/{id}/runs","summary":"Create a run from a template (steps are snapshotted)"},{"id":"SearchController_search","method":"GET","path":"/api/search","summary":"Universal cross-entity search by free-text query. Returns matching contacts, companies, and leads in a single response."},{"id":"files.upload","method":"POST","path":"/api/files/upload","scope":"files:write","summary":"Upload an image for creatives (max 5 MB)"},{"id":"files.images","method":"GET","path":"/api/files/images","scope":"files:read","summary":"List uploaded creative images for the tenant"},{"id":"FilesController_deleteImage","method":"DELETE","path":"/api/files/images/{filename}","summary":"Delete a tenant-scoped creative image"},{"id":"FilesController_uploadAsset","method":"POST","path":"/api/files/assets","scope":"files:write","summary":"Upload a tenant asset (signature, PDF photo, max 30 MB)"},{"id":"files.assets","method":"GET","path":"/api/files/assets","scope":"files:read","summary":"List tenant assets"},{"id":"FilesController_getAssetsQuota","method":"GET","path":"/api/files/assets/quota","scope":"files:read","summary":"Get tenant asset storage usage and quota"},{"id":"FilesController_deleteAsset","method":"DELETE","path":"/api/files/assets/{filename}","summary":"Delete a tenant asset"},{"id":"files.list","method":"GET","path":"/api/files","scope":"files:read","summary":"List file attachments for a contact, company or lead"},{"id":"FilesController_create","method":"POST","path":"/api/files","summary":"Create a file attachment record"},{"id":"FilesController_remove","method":"DELETE","path":"/api/files/{id}","summary":"Delete a file attachment record"},{"id":"FileServeController_serveImage","method":"GET","path":"/api/uploads/images/{tenantDbName}/{filename}","summary":"Serve a tenant-scoped uploaded image"},{"id":"FileServeController_serveTenantAsset","method":"GET","path":"/api/uploads/tenant-assets/{tenantDbName}/{filename}","summary":"Serve a tenant-scoped asset (signature, PDF photo)"},{"id":"FileServeController_serveDialogAttachment","method":"GET","path":"/api/uploads/dialog-attachments/{tenantDbName}/{filename}","summary":"Download an inbound dialog attachment (#176)"},{"id":"FileServeController_serveAvatar","method":"GET","path":"/api/uploads/avatars/{filename}","summary":"Serve a user avatar image"},{"id":"ActivitiesController_feed","method":"GET","path":"/api/activities/feed","scope":"activities:read","summary":"Unified tenant event feed (activities + emails) for /crm/events — filters: date range, type (ActivityType|EMAIL_IN|EMAIL_OUT), entityType (contact|lead|company); paginated, sorted by date desc"},{"id":"activities.list","method":"GET","path":"/api/activities","scope":"activities:read","summary":"List activities filtered by lead/contact/company/type"},{"id":"activities.create","method":"POST","path":"/api/activities","scope":"activities:write","summary":"Create an activity (call/task/note) linked to a lead/contact/company"},{"id":"ActivitiesController_update","method":"PATCH","path":"/api/activities/{id}","summary":"Update an activity (subject, description, due date, done flag)"},{"id":"ActivitiesController_remove","method":"DELETE","path":"/api/activities/{id}","summary":"Delete an activity by id"},{"id":"admin.queues","method":"GET","path":"/api/admin/queues","scope":"admin:read","summary":"Get stats for all BullMQ queues"},{"id":"AdminController_getScoringHealth","method":"GET","path":"/api/admin/scoring/health","scope":"admin:read","summary":"Scoring pipeline health: browser worker reachability and queue depths"},{"id":"AdminController_getQueueJobs","method":"GET","path":"/api/admin/queues/{name}/jobs","summary":"List jobs in a queue by status"},{"id":"AdminController_pauseQueue","method":"POST","path":"/api/admin/queues/{name}/pause","summary":"Pause a BullMQ queue"},{"id":"AdminController_resumeQueue","method":"POST","path":"/api/admin/queues/{name}/resume","summary":"Resume a BullMQ queue"},{"id":"AdminController_cancelQueueJob","method":"POST","path":"/api/admin/queues/{name}/jobs/{id}/cancel","summary":"Cancel a queue job by id"},{"id":"AdminController_retryQueueJob","method":"POST","path":"/api/admin/queues/{name}/jobs/{id}/retry","summary":"Retry a failed queue job"},{"id":"AdminController_cleanQueue","method":"POST","path":"/api/admin/queues/{name}/clean","summary":"Clean queue jobs (completed/failed)"},{"id":"AdminController_getStorageStats","method":"GET","path":"/api/admin/storage","scope":"admin:read","summary":"Get storage usage stats"},{"id":"AdminController_listPdfs","method":"GET","path":"/api/admin/storage/pdfs","scope":"admin:read","summary":"List stored PDFs with metadata"},{"id":"AdminController_cleanupPdfs","method":"POST","path":"/api/admin/storage/cleanup-pdfs","scope":"admin:write","summary":"Cleanup old PDFs from storage"},{"id":"admin.tenants","method":"GET","path":"/api/admin/tenants","scope":"admin:read","summary":"List all tenants with metadata"},{"id":"AdminController_toggleLdmAi","method":"PATCH","path":"/api/admin/tenants/{dbName}/ldm-ai","summary":"Toggle LDM AI for a tenant"},{"id":"AdminController_setLdmAiBalance","method":"PATCH","path":"/api/admin/tenants/{dbName}/ldm-ai/balance","summary":"Set / top up per-tenant LDM AI balance (USD)"},{"id":"AdminController_updateMaxStreams","method":"PATCH","path":"/api/admin/tenants/{dbName}/max-streams","summary":"Update max parallel streams for a tenant"},{"id":"AdminController_updateTransport","method":"PATCH","path":"/api/admin/tenants/{dbName}/transport","summary":"Update mail transport config for a tenant"},{"id":"AdminController_getInboxCheckTenants","method":"GET","path":"/api/admin/tenants/inbox-check","scope":"admin:read","summary":"List inbox-check status across tenants"},{"id":"AdminController_updateInboxCheckTenant","method":"PATCH","path":"/api/admin/tenants/{dbName}/inbox-check","summary":"Update inbox-check config for a tenant"},{"id":"AdminController_testInboxCheckTenant","method":"POST","path":"/api/admin/tenants/{dbName}/inbox-check/test","summary":"Run inbox-check test for a tenant"},{"id":"AdminController_getLdmAiUsage","method":"GET","path":"/api/admin/ldmai-usage","scope":"admin:read","summary":"Get LDM AI usage statistics"},{"id":"AdminController_getLdmAiQueueStats","method":"GET","path":"/api/admin/ldmai-queue","scope":"admin:read","summary":"Get LDM AI queue snapshot"},{"id":"AdminController_getAiMonitor","method":"GET","path":"/api/admin/ai-monitor","scope":"admin:read","summary":"Get AI monitor dashboard data"},{"id":"AdminController_getAiModelMapping","method":"GET","path":"/api/admin/ai-model-mapping","scope":"admin:read","summary":"Get AI model mapping configuration"},{"id":"admin.i18n","method":"GET","path":"/api/admin/i18n","scope":"admin:read","summary":"Get i18n translations bundle"},{"id":"AdminController_updateI18nKey","method":"PUT","path":"/api/admin/i18n/key","scope":"admin:write","summary":"Update a single i18n translation key"},{"id":"AdminController_deleteI18nKey","method":"DELETE","path":"/api/admin/i18n/key","scope":"admin:write","summary":"Delete an i18n translation key"},{"id":"AdminController_bulkUpdateI18n","method":"PUT","path":"/api/admin/i18n/bulk","scope":"admin:write","summary":"Bulk-update i18n translation keys"},{"id":"admin.memory.list","method":"GET","path":"/api/admin/memory","scope":"admin:read","summary":"List memory files"},{"id":"AdminController_memoryStats","method":"GET","path":"/api/admin/memory/stats","scope":"admin:read","summary":"Get memory storage stats"},{"id":"AdminController_readMemory","method":"GET","path":"/api/admin/memory/{filename}","summary":"Read a memory file by name"},{"id":"AdminController_saveMemory","method":"PUT","path":"/api/admin/memory/{filename}","summary":"Write a memory file by name"},{"id":"AdminController_deleteMemory","method":"DELETE","path":"/api/admin/memory/{filename}","summary":"Delete a memory file by name"},{"id":"AdminController_renameMemory","method":"POST","path":"/api/admin/memory/rename","scope":"admin:write","summary":"Rename a memory file"},{"id":"admin.security.overview","method":"GET","path":"/api/admin/security/overview","scope":"admin:read","summary":"Get security overview dashboard"},{"id":"AdminController_getPortStatus","method":"GET","path":"/api/admin/security/ports","scope":"admin:read","summary":"List open network ports detected on the host"},{"id":"AdminController_getSecurityScore","method":"GET","path":"/api/admin/security/score","scope":"admin:read","summary":"Get aggregate security score"},{"id":"AdminController_getRecommendations","method":"GET","path":"/api/admin/security/recommendations","scope":"admin:read","summary":"Get security hardening recommendations"},{"id":"AdminController_getIntegrity","method":"GET","path":"/api/admin/security/integrity","scope":"admin:read","summary":"Check file-integrity vs baseline"},{"id":"AdminController_initBaseline","method":"POST","path":"/api/admin/security/baseline","scope":"admin:write","summary":"Create a new file-integrity baseline"},{"id":"AdminController_runIntegrityCheck","method":"POST","path":"/api/admin/security/check","scope":"admin:write","summary":"Run an on-demand security check"},{"id":"AdminController_getIntrusions","method":"GET","path":"/api/admin/security/intrusions","scope":"admin:read","summary":"List detected intrusion attempts"},{"id":"AdminController_getAttackSummary","method":"GET","path":"/api/admin/security/summary","scope":"admin:read","summary":"Get security summary report"},{"id":"AdminController_getHoneypotEvents","method":"GET","path":"/api/admin/security/honeypot","scope":"admin:read","summary":"List recent honeypot events"},{"id":"AdminController_getHoneypotStats","method":"GET","path":"/api/admin/security/honeypot/stats","scope":"admin:read","summary":"Get aggregate honeypot statistics"},{"id":"AdminController_getLockdownStatus","method":"GET","path":"/api/admin/security/lockdown","scope":"admin:read","summary":"Get current lockdown state"},{"id":"AdminController_activateLockdown","method":"POST","path":"/api/admin/security/lockdown/activate","scope":"admin:write","summary":"Activate lockdown mode"},{"id":"AdminController_deactivateLockdown","method":"POST","path":"/api/admin/security/lockdown/deactivate","scope":"admin:write","summary":"Deactivate lockdown mode"},{"id":"AdminController_getLockdownHistory","method":"GET","path":"/api/admin/security/lockdown/history","scope":"admin:read","summary":"Get lockdown activation history"},{"id":"AdminController_getRecentEvents","method":"GET","path":"/api/admin/security/events","scope":"admin:read","summary":"List security events log"},{"id":"AdminController_getBackupStatus","method":"GET","path":"/api/admin/security/backups","scope":"admin:read","summary":"List available backups"},{"id":"AdminController_getPipelines","method":"GET","path":"/api/admin/pipelines","scope":"admin:read","summary":"List all pipelines (cross-tenant admin view)"},{"id":"HoneypotController_fakeAdminLoginGet","method":"GET","path":"/api/honeypot/admin-login","summary":"Honeypot fake admin login GET (logs attacker scan)"},{"id":"HoneypotController_fakeAdminLoginPost","method":"POST","path":"/api/honeypot/admin-login","summary":"Honeypot fake admin login POST (logs attacker credentials attempt)"},{"id":"HoneypotController_fakeEnv","method":"GET","path":"/api/honeypot/env","summary":"Honeypot fake .env file (logs secrets-scanner access)"},{"id":"HoneypotController_fakeWpAdmin","method":"GET","path":"/api/honeypot/wp-admin","summary":"Honeypot fake WordPress admin (logs WP-scanner access)"},{"id":"HoneypotController_fakePhpMyAdmin","method":"GET","path":"/api/honeypot/phpmyadmin","summary":"Honeypot fake phpMyAdmin (logs DB-scanner access)"},{"id":"HoneypotController_fakeActuator","method":"GET","path":"/api/honeypot/actuator","summary":"Honeypot fake Spring Boot actuator (logs probe access)"},{"id":"RpaController_poll","method":"GET","path":"/api/rpa/poll","summary":"Poll for available RPA work (queued jobs or unprocessed contacts)"},{"id":"RpaController_takeTask","method":"GET","path":"/api/rpa/take-task","summary":"Take one RPA job from a mailing and start preparation"},{"id":"RpaController_jobStatus","method":"GET","path":"/api/rpa/job-status","summary":"Poll RPA job status until ready"},{"id":"RpaController_fetchTask","method":"GET","path":"/api/rpa/fetch-task","summary":"Fetch prepared RPA task data for sending"},{"id":"RpaController_jobReport","method":"POST","path":"/api/rpa/job-report","summary":"Report the result of an RPA send job"},{"id":"RpaController_systemReport","method":"POST","path":"/api/rpa/system-report","summary":"Report a process-level RPA error not tied to a job"},{"id":"RpaController_systemStatus","method":"GET","path":"/api/rpa/system-status","summary":"Get RPA system health: errors, paused mailings, account stats"},{"id":"RpaController_systemReset","method":"POST","path":"/api/rpa/system-reset","summary":"Reset RPA system error counter and optionally resume paused mailings"},{"id":"RpaController_getNextBatch","method":"GET","path":"/api/rpa/next-batch","summary":"Legacy: fetch a fair round-robin batch of RPA items"},{"id":"RpaController_taskStatus","method":"GET","path":"/api/rpa/task-status","summary":"Legacy: get mailing-level RPA status with item counts"},{"id":"RpaController_report","method":"POST","path":"/api/rpa/report","summary":"Legacy: submit a batch report of RPA item send results"},{"id":"RpaController_releaseStale","method":"POST","path":"/api/rpa/release-stale","summary":"Legacy: release stale (stuck) RPA items back to queue"},{"id":"RpaController_requeueGet","method":"GET","path":"/api/rpa/requeue","summary":"Legacy: requeue RPA items in given statuses (GET form)"},{"id":"RpaController_requeuePost","method":"POST","path":"/api/rpa/requeue","summary":"Legacy: requeue RPA items in given statuses"},{"id":"CampaignsController_list","method":"GET","path":"/api/campaigns","summary":"List campaigns"},{"id":"CampaignsController_create","method":"POST","path":"/api/campaigns","summary":"Create a campaign"},{"id":"CampaignsController_overview","method":"GET","path":"/api/campaigns/overview","scope":"campaigns:read","summary":"Campaigns overview for dashboard mailings widget"},{"id":"CampaignsController_get","method":"GET","path":"/api/campaigns/{id}","summary":"Get a campaign by id"},{"id":"CampaignsController_update","method":"PATCH","path":"/api/campaigns/{id}","summary":"Update a campaign (creative pool, routing, status)"},{"id":"CampaignsController_remove","method":"DELETE","path":"/api/campaigns/{id}","summary":"Delete a campaign (cascades recipients; ACTIVE must be paused first)"},{"id":"CampaignsController_metrics","method":"GET","path":"/api/campaigns/{id}/metrics","summary":"Aggregated delivery metrics (sent/delivered/opened/clicked/errors/bounced/unsubscribed/complained/replied/inboxPlacement)"},{"id":"CampaignsController_sendReadiness","method":"GET","path":"/api/campaigns/{id}/send-readiness","summary":"Dry-run all send gates for a campaign: status, breaker, send window, sender pool, routing, inbox-check, due READY rows. Read-only, nothing is sent."},{"id":"CampaignsController_listRecipients","method":"GET","path":"/api/campaigns/{id}/recipients","summary":"List campaign recipients"},{"id":"CampaignsController_moveRecipientsStage","method":"POST","path":"/api/campaigns/{id}/recipients/move-stage","summary":"Move campaign recipients to a canvas stage (no send)"},{"id":"CampaignsController_rerenderRecipients","method":"POST","path":"/api/campaigns/{id}/recipients/rerender","summary":"Reset unsent recipients back to SCREENED for a fresh re-render"},{"id":"CampaignsController_reconcileFromDialogs","method":"POST","path":"/api/campaigns/{id}/reconcile-from-dialogs","summary":"One-time: reconcile campaign recipients from existing dialogs (migration)"},{"id":"CampaignsController_pour","method":"POST","path":"/api/campaigns/{id}/pour","summary":"Налить получателей в кампанию из КОНТАКТ-списка. Читает СТАТИЧЕСКОЕ членство списка (contactListMembership) — smart-фильтры НЕ разворачиваются, из списка КОМПАНИЙ напрямую налить нельзя. Флоу: сначала положить контакты в контакт-список (перечислить contactIds → contact-lists POST :id/contacts или contacts.bulk addToList с явными id), затем pour(listId). Идемпотентно (дедуп по email), фиксирует sourceConfig.listId для авто-долива новых членов."},{"id":"CampaignsController_push","method":"POST","path":"/api/campaigns/{id}/push","summary":"Push contacts directly into campaign (API-push, e.g. from form webhook)"},{"id":"CampaignsController_pourFromLeads","method":"POST","path":"/api/campaigns/{id}/pour-from-leads","summary":"Pour recipients from CRM leads filtered by pipeline/stage/interestStatus"},{"id":"CampaignsController_screen","method":"POST","path":"/api/campaigns/{id}/screen","summary":"Скрининг NEW-получателей (suppression + стоп-лист): NEW→SCREENED|SKIPPED. Шаг конвейера между pour и prepare."},{"id":"CampaignsController_prepare","method":"POST","path":"/api/campaigns/{id}/prepare","summary":"Рендер креатива + pre-flight аудит для SCREENED-получателей (SCREENED→READY|CREATIVE_FAILED). Батчами: передавай limit и зови повторно, пока remaining>0."},{"id":"CampaignsController_dispatch","method":"POST","path":"/api/campaigns/{id}/dispatch","summary":"Assign sender account + schedule to READY recipients (no send yet)"},{"id":"CampaignsController_send","method":"POST","path":"/api/campaigns/{id}/send","summary":"Hand dispatched READY recipients to the mail_outbox queue (limit=1 for first test send)"},{"id":"CampaignsController_syncEvents","method":"POST","path":"/api/campaigns/{id}/sync-events","summary":"Sync open/click/bounce events from Dialog records back to recipients"},{"id":"CampaignsController_resume","method":"POST","path":"/api/campaigns/{id}/resume","summary":"Resume a PAUSED campaign (reset circuit breaker)"},{"id":"CampaignsController_getRecipient","method":"GET","path":"/api/campaigns/{id}/recipients/{rid}","summary":"Get a recipient with its event log"},{"id":"EmailVerificationController_verifyOne","method":"POST","path":"/api/verify","summary":"Verify a single email address synchronously"},{"id":"EmailVerificationController_verifyBatch","method":"POST","path":"/api/verify/batch","scope":"email:send","summary":"Verify a batch of email addresses synchronously"},{"id":"best-send-time.calc","method":"POST","path":"/api/best-send-time","scope":"mailing:read","summary":"Resolve recommended send time for a contact/lead/dossier (side-effect-free)"},{"id":"CanvasController_getFlow","method":"GET","path":"/api/canvas/{id}/flow","summary":"Get the canvas flow definition of a campaign"},{"id":"CanvasController_putFlow","method":"PUT","path":"/api/canvas/{id}/flow","summary":"Replace the canvas flow definition (whole document)"},{"id":"CanvasController_stats","method":"GET","path":"/api/canvas/{id}/stats","summary":"Per-step canvas stats (GROUP BY canvasStage)"},{"id":"CanvasController_enrollments","method":"GET","path":"/api/canvas/{id}/enrollments","summary":"List canvas enrollments (reuse campaign recipients)"},{"id":"CanvasController_tick","method":"POST","path":"/api/canvas/{id}/tick","summary":"Run one orchestrator tick: claim → bring to READY → advance (НЕ шлёт; единая точка отправки забирает READY сама)"},{"id":"marking.patterns.list","method":"GET","path":"/api/marking/patterns","scope":"marking:read","summary":"List all marking patterns"},{"id":"marking.patterns.create","method":"POST","path":"/api/marking/patterns","scope":"marking:write","summary":"Create a new marking pattern"},{"id":"MarkingController_togglePattern","method":"PATCH","path":"/api/marking/patterns/{id}/toggle","summary":"Enable or disable a marking pattern"},{"id":"MarkingController_deletePattern","method":"DELETE","path":"/api/marking/patterns/{id}","summary":"Delete a marking pattern"},{"id":"marking.classify","method":"POST","path":"/api/marking/classify","scope":"marking:read","summary":"Classify a message against the marking patterns"},{"id":"MarkingController_classifyDialog","method":"POST","path":"/api/marking/dialogs/{id}/classify","summary":"Classify a specific dialog against the marking patterns"},{"id":"provider-configs.list","method":"GET","path":"/api/provider-configs","scope":"settings:read","summary":"List all email provider configurations"},{"id":"ProviderConfigController_resolve","method":"GET","path":"/api/provider-configs/resolve","scope":"settings:read","summary":"Resolve the email provider by domain"},{"id":"ProviderConfigController_getOne","method":"GET","path":"/api/provider-configs/{provider}","summary":"Get a single provider configuration by provider key"},{"id":"ProviderConfigController_upsert","method":"PUT","path":"/api/provider-configs/{provider}","summary":"Upsert a provider configuration"},{"id":"ProviderConfigController_remove","method":"DELETE","path":"/api/provider-configs/{provider}","summary":"Delete a provider configuration"},{"id":"ProviderConfigController_toggle","method":"PATCH","path":"/api/provider-configs/{provider}/toggle","summary":"Enable or disable a provider configuration"},{"id":"ProviderConfigController_addDomain","method":"POST","path":"/api/provider-configs/{provider}/domains","summary":"Add a domain mapping to a provider configuration"},{"id":"ProviderConfigController_removeDomain","method":"DELETE","path":"/api/provider-configs/{provider}/domains/{pattern}","summary":"Remove a domain mapping from a provider configuration"},{"id":"LegalController_getTerms","method":"GET","path":"/api/legal/terms","summary":"Get the current terms of service text (public)"},{"id":"LegalController_updateTerms","method":"PUT","path":"/api/legal/terms","scope":"legal:write","summary":"Update the terms of service text (SUPER only)"},{"id":"legal.list","method":"GET","path":"/api/legal","scope":"legal:read","summary":"List all legal documents (SUPER only)"},{"id":"connectors.tilda.webhook","method":"POST","path":"/api/connectors/tilda/webhook","scope":"connectors:write","summary":"Tilda form webhook (отключён — требует авторизации, см. #193)"},{"id":"ConnectorsController_lookupInn","method":"GET","path":"/api/connectors/sbis/inn/{inn}","summary":"Lookup Russian company by INN from AMS database"},{"id":"connectors.dadata","method":"GET","path":"/api/connectors/dadata/name","scope":"connectors:read","summary":"Normalize Russian full name via DaData API"},{"id":"SharePublicController_getOgHtml","method":"GET","path":"/api/share-og/{code}","summary":"Render OG meta-tag HTML for bot crawlers by short code"},{"id":"SharePublicController_getByShortCode","method":"GET","path":"/api/s/{code}","summary":"Get publicly-shared entity by short code (no auth)"},{"id":"SharePublicController_getShared","method":"GET","path":"/api/share-public/{token}","summary":"Get publicly-shared entity by legacy full token (no auth)"},{"id":"HealthController_liveness","method":"GET","path":"/api/health","summary":"Liveness probe"},{"id":"HealthController_capacity","method":"GET","path":"/api/health/capacity","summary":"Resource capacity check for load admission"},{"id":"UnsubscribeController_handleUnsubscribe","method":"GET","path":"/api/unsubscribe/{token}","summary":"Handle unsubscribe click from email link (public)"},{"id":"UnsubscribeController_oneClickUnsubscribe","method":"POST","path":"/api/unsubscribe/{token}","summary":"RFC 8058 one-click unsubscribe endpoint"},{"id":"webhooks.list","method":"GET","path":"/api/webhooks","scope":"webhooks:read","summary":"List webhook endpoints"},{"id":"webhooks.create","method":"POST","path":"/api/webhooks","scope":"webhooks:write","summary":"Create a webhook endpoint"},{"id":"WebhooksController_update","method":"PATCH","path":"/api/webhooks/{id}","summary":"Update a webhook endpoint"},{"id":"WebhooksController_remove","method":"DELETE","path":"/api/webhooks/{id}","summary":"Delete a webhook endpoint"},{"id":"WebhooksController_deliveries","method":"GET","path":"/api/webhooks/{id}/deliveries","summary":"List delivery history for a webhook endpoint"},{"id":"WebhooksController_retry","method":"POST","path":"/api/webhooks/deliveries/{id}/retry","summary":"Retry a single webhook delivery"},{"id":"WebhooksController_retrigger","method":"POST","path":"/api/webhooks/{id}/retrigger","summary":"Retrigger the last N deliveries for a webhook endpoint"},{"id":"AgentCardController_health","method":"GET","path":"/api/v1/health","summary":"Public API health check"},{"id":"AgentCardController_card","method":"GET","path":"/api/v1/.well-known/agent-card.json","summary":"Get the LDM-proprietary agent card"},{"id":"AgentCardController_cardA2A","method":"GET","path":"/api/v1/.well-known/agent.json","summary":"Get the A2A 0.2.5-compliant agent card"},{"id":"AgentGuideController_guide","method":"GET","path":"/api/v1/agent-guide","summary":"Expert guide: capability map + recommended flows for MCP/A2A agents"},{"id":"AgentGuideAdminController_getOverrides","method":"GET","path":"/api/admin/agent-guide/overrides","scope":"admin:read","summary":"Get the editable agent-guide overrides (raw JSON overlay + meta)"},{"id":"AgentGuideAdminController_putOverrides","method":"PUT","path":"/api/admin/agent-guide/overrides","scope":"admin:write","summary":"Replace the agent-guide overrides. Body: { domains?, operations?, controllerDomain? } — field-level overlay on the code defaults. Empty/omitted fields fall back to defaults."},{"id":"AgentGuideAdminController_getEffective","method":"GET","path":"/api/admin/agent-guide/effective","scope":"admin:read","summary":"Preview the effective (defaults + overrides) guide map"},{"id":"AgentGuideAdminController_coverage","method":"GET","path":"/api/admin/agent-guide/coverage","scope":"admin:read","summary":"Guidance coverage report: how many MCP tools have op-level guidance vs domain-fallback vs none. Shows honestly where the expert layer is empty."},{"id":"DeliverabilityController_startRelayReach","method":"POST","path":"/api/deliverability/probe/relay-reach","scope":"deliverability:write","summary":"C1: probe whether the given relay can deliver to the given providers (Layer 1 neutral baseline)"},{"id":"DeliverabilityController_startCreativeThroughRelay","method":"POST","path":"/api/deliverability/probe/creative-through-relay","scope":"deliverability:write","summary":"C2: probe whether a specific creative reaches inbox through (relay × provider)"},{"id":"DeliverabilityController_getMatrix","method":"GET","path":"/api/deliverability/matrix","scope":"deliverability:read","summary":"Get the deliverability matrix for the tenant (baseline / creative / block-rule per relay × provider)"},{"id":"DeliverabilityController_startCreativeTune","method":"POST","path":"/api/deliverability/probe/creative-tune","scope":"deliverability:write","summary":"C3: iteratively tune a creative (remove markers) until it reaches inbox via (relay, provider)"},{"id":"DeliverabilityController_startFullPipeline","method":"POST","path":"/api/deliverability/probe/full-pipeline","scope":"deliverability:write","summary":"Full pipeline: run C1 across all (relay × provider) and auto-chain C2/C3 via worker"},{"id":"DeliverabilityController_promoteTunedVariant","method":"POST","path":"/api/deliverability/tuned-variants/{id}/promote","summary":"Promote a tuned variant to a new Creative row in the tenant"},{"id":"DeliverabilityController_getJobStatus","method":"GET","path":"/api/deliverability/probe/{jobId}","summary":"Get aggregate status for a probe batch (jobId)"},{"id":"DeliverabilityController_cancelProbeJob","method":"DELETE","path":"/api/deliverability/probe/{jobId}","summary":"Cancel pending probes in a batch (in-flight workers no-op safely)"},{"id":"DeliverabilityController_listProbes","method":"GET","path":"/api/deliverability/probes","scope":"deliverability:read","summary":"List probe history with filters (raw audit-style log)"},{"id":"DeliverabilityController_createManualBlockRule","method":"POST","path":"/api/deliverability/block-rules","scope":"deliverability:write","summary":"Create a manual block rule (defaults to category=should_not_send, reason=manual)"},{"id":"DeliverabilityController_listBlockRules","method":"GET","path":"/api/deliverability/block-rules","scope":"deliverability:read","summary":"List active block rules for the tenant"},{"id":"DeliverabilityController_deleteBlockRule","method":"DELETE","path":"/api/deliverability/block-rules/{id}","summary":"Delete a block rule (manual unblock) — narrower scope required"},{"id":"DeliverabilityController_listTunedVariants","method":"GET","path":"/api/deliverability/tuned-variants","scope":"deliverability:read","summary":"List Layer-3 tuned creative variants (optionally filtered by parent creativeId)"},{"id":"EmailAccountDeliverabilityController_getAccountSnapshot","method":"GET","path":"/api/email-accounts/{id}/deliverability","summary":"Embedded deliverability snapshot for this email account (providers × {baseline, creative, blocked})"},{"id":"EmailAccountDeliverabilityController_probeAccount","method":"POST","path":"/api/email-accounts/{id}/deliverability/probe","summary":"\"Probe now\" — convenience C1 trigger scoped to this account"},{"id":"EmailAccountDeliverabilityController_unblockProvider","method":"DELETE","path":"/api/email-accounts/{id}/deliverability/block-rules/{provider}","summary":"Unblock a (this account × provider) block rule — narrower scope required"},{"id":"share.create","method":"POST","path":"/api/share-links","scope":"share:write","summary":"Create a share link for an entity"},{"id":"share.list","method":"GET","path":"/api/share-links","scope":"share:read","summary":"List share links for an entity"},{"id":"ShareLinksController_revoke","method":"DELETE","path":"/api/share-links/{id}","summary":"Revoke a share link"},{"id":"exports.columns","method":"GET","path":"/api/exports/columns","scope":"exports:read","summary":"List exportable columns and groups for an entity"},{"id":"exports.create","method":"POST","path":"/api/exports","scope":"exports:write","summary":"Create an export job"},{"id":"exports.list","method":"GET","path":"/api/exports","scope":"exports:read","summary":"List my export jobs"},{"id":"ExportsController_status","method":"GET","path":"/api/exports/{id}","summary":"Get the status of an export job"},{"id":"ExportsController_download","method":"GET","path":"/api/exports/{id}/download","summary":"Download a completed export file"},{"id":"A2AController_dispatch","method":"POST","path":"/api/a2a","summary":"A2A JSON-RPC 2.0 dispatch (single or batch, supports SSE for streaming methods)"},{"id":"ApiMonitorController_list","method":"GET","path":"/api/admin/api-monitor","summary":"List API request log entries with filters (SUPER only)"},{"id":"ApiMonitorController_aggregates","method":"GET","path":"/api/admin/api-monitor/aggregates","scope":"admin:read","summary":"Get aggregated API monitor metrics (RPS, latency percentiles, top paths)"},{"id":"ApiMonitorController_mcpTools","method":"GET","path":"/api/admin/api-monitor/mcp/tools","scope":"admin:read","summary":"MCP tools usage breakdown — per-tool counts, latency p95, error rate. SUPER only. Used by the MCP tab on the admin API monitor page."},{"id":"ApiMonitorController_mcpKeys","method":"GET","path":"/api/admin/api-monitor/mcp/keys","scope":"admin:read","summary":"Per-bearer-key usage — count, error rate, top-3 tools per key. SUPER only."},{"id":"ApiMonitorController_mcpTimeseries","method":"GET","path":"/api/admin/api-monitor/mcp/timeseries","scope":"admin:read","summary":"MCP requests time series bucketed by N minutes (default 60). Optional toolName filter for per-tool charts."},{"id":"ApiTestsController_catalog","method":"GET","path":"/api/admin/api-tests/catalog","scope":"admin:read","summary":"List the catalog of synthetic API test suites"},{"id":"ApiTestsController_run","method":"POST","path":"/api/admin/api-tests/run","scope":"admin:write","summary":"Run a synthetic API test suite (SUPER only)"},{"id":"ApiTestsController_list","method":"GET","path":"/api/admin/api-tests/runs","scope":"admin:read","summary":"List recent synthetic API test runs"},{"id":"ApiTestsController_get","method":"GET","path":"/api/admin/api-tests/runs/{id}","summary":"Get details of a single synthetic API test run"},{"id":"AllowlistController_list","method":"GET","path":"/api/allowlist","summary":"List allowlist entries with optional type/search filters"},{"id":"AllowlistController_create","method":"POST","path":"/api/allowlist","summary":"Create an allowlist entry (email or domain)"},{"id":"AllowlistController_check","method":"GET","path":"/api/allowlist/check","scope":"suppression:read","summary":"Check whether an email/domain is allowlisted"},{"id":"AllowlistController_bulkCreate","method":"POST","path":"/api/allowlist/bulk","scope":"suppression:write","summary":"Bulk-create allowlist entries (up to 1000)"},{"id":"AllowlistController_delete","method":"DELETE","path":"/api/allowlist/{id}","summary":"Delete an allowlist entry by id"},{"id":"SequencesController_list","method":"GET","path":"/api/sequences","summary":"List email sequences"},{"id":"SequencesController_create","method":"POST","path":"/api/sequences","summary":"Create an email sequence"},{"id":"SequencesController_get","method":"GET","path":"/api/sequences/{id}","summary":"Get a sequence by id"},{"id":"SequencesController_update","method":"PATCH","path":"/api/sequences/{id}","summary":"Update a sequence"},{"id":"SequencesController_delete","method":"DELETE","path":"/api/sequences/{id}","summary":"Delete a sequence"},{"id":"SequencesController_addStep","method":"POST","path":"/api/sequences/{id}/steps","summary":"Add a step to a sequence"},{"id":"SequencesController_updateStep","method":"PATCH","path":"/api/sequences/{id}/steps/{stepId}","summary":"Update a sequence step"},{"id":"SequencesController_deleteStep","method":"DELETE","path":"/api/sequences/{id}/steps/{stepId}","summary":"Delete a sequence step"},{"id":"SequencesController_listVariants","method":"GET","path":"/api/sequences/{id}/steps/{stepId}/variants","summary":"List A/B variants on a step"},{"id":"SequencesController_addVariant","method":"POST","path":"/api/sequences/{id}/steps/{stepId}/variants","summary":"Add an A/B variant to a step"},{"id":"SequencesController_updateVariant","method":"PATCH","path":"/api/sequences/{id}/steps/{stepId}/variants/{variantId}","summary":"Update an A/B variant"},{"id":"SequencesController_deleteVariant","method":"DELETE","path":"/api/sequences/{id}/steps/{stepId}/variants/{variantId}","summary":"Delete an A/B variant"},{"id":"SequencesController_variantStats","method":"GET","path":"/api/sequences/{id}/steps/{stepId}/variants/stats","summary":"Get A/B variant statistics for a step"},{"id":"SequencesController_enroll","method":"POST","path":"/api/sequences/{id}/enroll","summary":"Enroll contacts into a sequence"},{"id":"SequencesController_listEnrollments","method":"GET","path":"/api/sequences/{id}/enrollments","summary":"List enrollments for a sequence"},{"id":"SequencesController_pauseEnrollment","method":"POST","path":"/api/sequences/enrollments/{eid}/pause","summary":"Pause an enrollment"},{"id":"SequencesController_resumeEnrollment","method":"POST","path":"/api/sequences/enrollments/{eid}/resume","summary":"Resume an enrollment"},{"id":"SequencesController_cancelEnrollment","method":"POST","path":"/api/sequences/enrollments/{eid}/cancel","summary":"Cancel an enrollment"},{"id":"AgencyController_list","method":"GET","path":"/api/agency","summary":"List agency sub-accounts and parent tenant metadata"},{"id":"AgencyController_create","method":"POST","path":"/api/agency","summary":"Create a new sub-account tenant under the caller"},{"id":"AgencyController_stats","method":"GET","path":"/api/agency/stats","scope":"admin:read","summary":"Aggregate stats per sub-account child"},{"id":"AgencyController_detach","method":"DELETE","path":"/api/agency/{childId}","summary":"Detach (un-parent) a sub-account from the agency"},{"id":"AuditController_list","method":"GET","path":"/api/audit-events","summary":"List audit events with filters (action, actor, target, date range)"},{"id":"AuditController_manualWrite","method":"POST","path":"/api/audit-events","summary":"Manually write an audit event (used by agents to attribute their actions)"},{"id":"AuditController_aggregates","method":"GET","path":"/api/audit-events/aggregates","scope":"admin:read","summary":"Get aggregate audit-event counts over a date range"},{"id":"BrandingController_get","method":"GET","path":"/api/branding","summary":"Get resolved white-label branding for the caller tenant (defaults merged)"},{"id":"BrandingController_update","method":"PATCH","path":"/api/branding","summary":"Partially update tenant white-label branding"},{"id":"BrandingController_reset","method":"DELETE","path":"/api/branding","summary":"Reset tenant white-label branding back to defaults"},{"id":"CohortMetricsController_funnel","method":"GET","path":"/api/cohort-metrics/funnel","scope":"mailing:read","summary":"Get sequence funnel metrics for a date range"},{"id":"CohortMetricsController_latency","method":"GET","path":"/api/cohort-metrics/latency","scope":"mailing:read","summary":"Get reply latency metrics for a sequence/date range"},{"id":"CohortMetricsController_cohorts","method":"GET","path":"/api/cohort-metrics/cohorts","scope":"mailing:read","summary":"Get cohort breakdown for a sequence/date range"},{"id":"EnrichmentController_company","method":"POST","path":"/api/enrichment/company","scope":"connectors:read","summary":"Enrich a company by domain, INN or name"},{"id":"EnrichmentController_findEmail","method":"POST","path":"/api/enrichment/email","scope":"connectors:read","summary":"Find an email address from name and domain"},{"id":"DomainsController_check","method":"POST","path":"/api/domains/dns-check","scope":"mailing:read","summary":"Run DNS health check for a single domain"},{"id":"DomainsController_bulk","method":"POST","path":"/api/domains/dns-check/bulk","scope":"mailing:read","summary":"Run DNS health check for up to 20 domains"},{"id":"PromptTemplatesController_list","method":"GET","path":"/api/prompt-templates","summary":"List prompt templates with optional filters"},{"id":"PromptTemplatesController_create","method":"POST","path":"/api/prompt-templates","summary":"Create a new prompt template"},{"id":"PromptTemplatesController_get","method":"GET","path":"/api/prompt-templates/{id}","summary":"Get a single prompt template by id"},{"id":"PromptTemplatesController_update","method":"PATCH","path":"/api/prompt-templates/{id}","summary":"Update a prompt template"},{"id":"PromptTemplatesController_delete","method":"DELETE","path":"/api/prompt-templates/{id}","summary":"Delete a prompt template"},{"id":"PromptTemplatesController_render","method":"POST","path":"/api/prompt-templates/{idOrName}/render","summary":"Render a prompt template (by id or name) with caller variables"},{"id":"CustomEventsController_track","method":"POST","path":"/api/custom-events","summary":"Track a single custom event"},{"id":"CustomEventsController_list","method":"GET","path":"/api/custom-events","summary":"List custom events with filters and pagination"},{"id":"CustomEventsController_bulkTrack","method":"POST","path":"/api/custom-events/bulk","scope":"events:write","summary":"Track up to 500 custom events in one request"},{"id":"CustomEventsController_aggregates","method":"GET","path":"/api/custom-events/aggregates","scope":"events:read","summary":"Get aggregated custom event counts by date range"},{"id":"CustomObjectsController_listDefs","method":"GET","path":"/api/custom-objects/defs","scope":"crm:read","summary":"List custom object definitions"},{"id":"CustomObjectsController_createDef","method":"POST","path":"/api/custom-objects/defs","scope":"crm:write","summary":"Create a custom object definition"},{"id":"CustomObjectsController_getDef","method":"GET","path":"/api/custom-objects/defs/{slug}","summary":"Get a custom object definition by slug"},{"id":"CustomObjectsController_updateDef","method":"PATCH","path":"/api/custom-objects/defs/{slug}","summary":"Update a custom object definition"},{"id":"CustomObjectsController_deleteDef","method":"DELETE","path":"/api/custom-objects/defs/{slug}","summary":"Delete a custom object definition"},{"id":"CustomObjectsController_listRecords","method":"GET","path":"/api/custom-objects/{slug}/records","summary":"List records of a custom object"},{"id":"CustomObjectsController_createRecord","method":"POST","path":"/api/custom-objects/{slug}/records","summary":"Create a record of a custom object"},{"id":"CustomObjectsController_getRecord","method":"GET","path":"/api/custom-objects/{slug}/records/{id}","summary":"Get a custom object record by id or externalId"},{"id":"CustomObjectsController_updateRecord","method":"PATCH","path":"/api/custom-objects/{slug}/records/{id}","summary":"Update a custom object record"},{"id":"CustomObjectsController_deleteRecord","method":"DELETE","path":"/api/custom-objects/{slug}/records/{id}","summary":"Delete a custom object record"},{"id":"icp.tasks.list","method":"GET","path":"/api/icp-tasks","scope":"icp:read","summary":"List ICP tasks with pagination and status filter"},{"id":"icp.tasks.create","method":"POST","path":"/api/icp-tasks","scope":"icp:write","summary":"Create a new ICP task"},{"id":"IcpExtensionController_findById","method":"GET","path":"/api/icp-tasks/{id}","summary":"Get an ICP task by id"},{"id":"IcpExtensionController_update","method":"PATCH","path":"/api/icp-tasks/{id}","summary":"Update an ICP task"},{"id":"IcpExtensionController_remove","method":"DELETE","path":"/api/icp-tasks/{id}","summary":"Delete an ICP task"},{"id":"IcpExtensionController_regenerateKey","method":"POST","path":"/api/icp-tasks/{id}/regenerate-key","summary":"Regenerate the project key for an ICP task"},{"id":"IcpExtensionController_getStatistics","method":"GET","path":"/api/icp-tasks/{id}/statistics","summary":"Get statistics for an ICP task"},{"id":"IcpExtensionController_getItems","method":"GET","path":"/api/icp-tasks/{id}/items","summary":"List items belonging to an ICP task"},{"id":"IcpExtensionController_downloadExtension","method":"GET","path":"/api/icp-tasks/{id}/download-extension","summary":"Download a pre-built Chrome extension zip for an ICP task"},{"id":"IcpExtApiController_authorize","method":"GET","path":"/api/ext/auth","summary":"Authorize the Chrome extension by project key"},{"id":"IcpExtApiController_getNextItem","method":"GET","path":"/api/ext/icpreview/next","summary":"Get the next ICP review item for the extension"},{"id":"IcpExtApiController_analyzeAi","method":"POST","path":"/api/ext/icpreview/ai","summary":"Analyze an ICP review item with AI"},{"id":"IcpExtApiController_complete","method":"POST","path":"/api/ext/icpreview/complete","summary":"Mark an ICP review item as completed"},{"id":"IcpExtApiController_getFormAssistConfig","method":"GET","path":"/api/ext/formassist/config","summary":"Get form assist configuration for the extension"},{"id":"IcpExtApiController_formAssistAi","method":"POST","path":"/api/ext/formassist/ai","summary":"Run AI form-fill suggestion for the extension"},{"id":"IcpExtApiController_formAssistComplete","method":"POST","path":"/api/ext/formassist/complete","summary":"Report form-assist completion from the extension"},{"id":"IcpExtApiController_getSendEmailStats","method":"GET","path":"/api/ext/sendemail/stats","summary":"Get send-email stats for the extension"},{"id":"IcpExtApiController_captureEmail","method":"POST","path":"/api/ext/sendemail/capture","summary":"Capture an email address from the extension"},{"id":"IcpExtApiController_generateMessage","method":"POST","path":"/api/ext/messenger/generate","summary":"Generate a messenger message (channel = vk|telegram|whatsapp|linkedin)"},{"id":"IcpExtApiController_messengerComplete","method":"POST","path":"/api/ext/messenger/complete","summary":"Report messenger send completion (creates/links a Contact by url)"},{"id":"IcpExtApiController_presentation","method":"POST","path":"/api/ext/presentation","summary":"Generate a presentation PDF (mode = attach → base64 | link → OG url)"},{"id":"IcpExtApiController_presentationPdf","method":"GET","path":"/api/ext/presentation/pdf/{filename}","summary":"Serve a presentation PDF by filename (no key, public link)"},{"id":"IcpExtApiController_presentationOg","method":"GET","path":"/api/ext/presentation/{token}","summary":"Public OG preview page for a presentation link (no key)"},{"id":"LinkedinExtApiController_session","method":"POST","path":"/api/ext/linkedin/session","summary":"Залить/обновить сессию (куки авторизованного браузера)"},{"id":"LinkedinExtApiController_next","method":"GET","path":"/api/ext/linkedin/next","summary":"Взять следующее due-действие (атомарно). Пусто → 204"},{"id":"LinkedinExtApiController_report","method":"POST","path":"/api/ext/linkedin/report","summary":"Отчёт об исполнении действия"},{"id":"LinkedinExtApiController_events","method":"POST","path":"/api/ext/linkedin/events","summary":"События виджета (accept/reply/warning/challenge)"},{"id":"LinkedinExtApiController_config","method":"GET","path":"/api/ext/linkedin/config","summary":"Клиентский конфиг: тумблеры + guard-rails"},{"id":"LinkedinExtApiController_heartbeat","method":"POST","path":"/api/ext/linkedin/heartbeat","summary":"Heartbeat виджета (+опц. свежие куки)"},{"id":"linkedin.integration","method":"GET","path":"/api/linkedin/integration","scope":"linkedin:read","summary":"Статус интеграции LinkedIn (тумблер, дефолты)"},{"id":"linkedin.integration.update","method":"PATCH","path":"/api/linkedin/integration","scope":"linkedin:write","summary":"Включить/выключить модуль, kill-switch, дефолты"},{"id":"linkedin.accounts","method":"GET","path":"/api/linkedin/accounts","scope":"linkedin:read","summary":"Список LinkedIn-аккаунтов (без куки)"},{"id":"LinkedinController_getAccount","method":"GET","path":"/api/linkedin/accounts/{id}","summary":"Аккаунт по id (без куки)"},{"id":"LinkedinController_patchAccount","method":"PATCH","path":"/api/linkedin/accounts/{id}","summary":"Изменить лимиты/окна/паузу аккаунта"},{"id":"LinkedinController_disconnect","method":"POST","path":"/api/linkedin/accounts/{id}/disconnect","summary":"Отозвать сессию (стереть куки)"},{"id":"linkedin.campaigns","method":"GET","path":"/api/linkedin/campaigns","scope":"linkedin:read","summary":"Список кампаний"},{"id":"linkedin.campaign.create","method":"POST","path":"/api/linkedin/campaigns","scope":"linkedin:write","summary":"Создать кампанию"},{"id":"LinkedinController_patchCampaign","method":"PATCH","path":"/api/linkedin/campaigns/{id}","summary":"Изменить кампанию (имя/статус/сценарий)"},{"id":"LinkedinController_pourLeads","method":"POST","path":"/api/linkedin/campaigns/{id}/leads","summary":"Налить лидов в кампанию"},{"id":"linkedin.scenarios","method":"GET","path":"/api/linkedin/scenarios","scope":"linkedin:read","summary":"Список сценариев"},{"id":"LinkedinController_createScenario","method":"POST","path":"/api/linkedin/scenarios","scope":"linkedin:write","summary":"Создать сценарий"},{"id":"linkedin.stats","method":"GET","path":"/api/linkedin/stats","scope":"linkedin:read","summary":"Дашборд: воронка + acceptance/reply-rate"},{"id":"admin.phantom.profiles","method":"GET","path":"/api/phantom-browser/profiles","scope":"admin:read","summary":"List all Phantom browser profiles"},{"id":"PhantomBrowserController_createProfile","method":"POST","path":"/api/phantom-browser/profiles","scope":"admin:write","summary":"Create a new Phantom browser profile"},{"id":"PhantomBrowserController_syncProfiles","method":"POST","path":"/api/phantom-browser/profiles/sync","scope":"admin:write","summary":"Re-send the profiles list to the connected Phantom client"},{"id":"PhantomBrowserController_getProfile","method":"GET","path":"/api/phantom-browser/profiles/{id}","summary":"Get a single Phantom browser profile by id"},{"id":"PhantomBrowserController_updateProfile","method":"PUT","path":"/api/phantom-browser/profiles/{id}","summary":"Update a Phantom browser profile"},{"id":"PhantomBrowserController_deleteProfile","method":"DELETE","path":"/api/phantom-browser/profiles/{id}","summary":"Delete a Phantom browser profile"},{"id":"PhantomBrowserController_getClientStatus","method":"GET","path":"/api/phantom-browser/client/status","scope":"admin:read","summary":"Get the Phantom desktop client connection status"},{"id":"PhantomBrowserController_regenerateToken","method":"POST","path":"/api/phantom-browser/client/token/regenerate","scope":"admin:write","summary":"Regenerate the Phantom client auth token"},{"id":"PhantomBrowserController_launchProfile","method":"POST","path":"/api/phantom-browser/profiles/{id}/launch","summary":"Launch a profile on the user's Phantom desktop client"},{"id":"PhantomBrowserController_stopProfile","method":"POST","path":"/api/phantom-browser/profiles/{id}/stop","summary":"Stop a running profile on the Phantom desktop client"},{"id":"PhantomBrowserController_navigate","method":"POST","path":"/api/phantom-browser/profiles/{id}/navigate","summary":"Navigate the Phantom browser profile to a URL"},{"id":"PhantomBrowserController_screenshot","method":"POST","path":"/api/phantom-browser/profiles/{id}/screenshot","summary":"Take a screenshot in the Phantom browser profile (base64 JPEG)"},{"id":"PhantomBrowserController_screenshotImage","method":"GET","path":"/api/phantom-browser/profiles/{id}/screenshot.jpg","summary":"Get the latest Phantom browser screenshot as a JPEG image"},{"id":"PhantomBrowserController_getHtml","method":"GET","path":"/api/phantom-browser/profiles/{id}/html","summary":"Get the current Phantom browser page's HTML"},{"id":"PhantomBrowserController_getPageInfo","method":"GET","path":"/api/phantom-browser/profiles/{id}/page-info","summary":"Get the current Phantom browser page URL and title"},{"id":"PhantomBrowserController_executeJs","method":"POST","path":"/api/phantom-browser/profiles/{id}/execute","summary":"Execute JavaScript in the Phantom browser page context"},{"id":"PhantomBrowserController_click","method":"POST","path":"/api/phantom-browser/profiles/{id}/click","summary":"Click an element in the Phantom browser by CSS selector"},{"id":"PhantomBrowserController_typeText","method":"POST","path":"/api/phantom-browser/profiles/{id}/type","summary":"Type text into a focused element or selector in the Phantom browser"},{"id":"PhantomBrowserController_getCookies","method":"GET","path":"/api/phantom-browser/profiles/{id}/cookies","summary":"Get cookies for the current Phantom browser page"},{"id":"PhantomBrowserController_setCookies","method":"POST","path":"/api/phantom-browser/profiles/{id}/cookies","summary":"Set cookies on the current Phantom browser page — lets the worker browse a site already logged-in. Accepts the Cookie-Editor / EditThisCookie export format directly (or the plain CDP shape); the server normalizes it (expirationDate→expires, sameSite no_restriction→None, drops hostOnly/session/storeId). Example body: { \"cookies\": [ { \"domain\": \".linkedin.com\", \"name\": \"li_at\", \"value\": \"AQ...\", \"path\": \"/\", \"expirationDate\": 1814817974.7, \"secure\": true, \"httpOnly\": true, \"sameSite\": \"no_restriction\" } ] }"},{"id":"PhantomBrowserController_scroll","method":"POST","path":"/api/phantom-browser/profiles/{id}/scroll","summary":"Scroll the current Phantom browser page"},{"id":"PhantomBrowserController_waitFor","method":"POST","path":"/api/phantom-browser/profiles/{id}/wait","summary":"Wait for a selector to appear in the Phantom browser page"},{"id":"PhantomBrowserController_solveCaptcha","method":"POST","path":"/api/phantom-browser/profiles/{id}/solve-captcha","summary":"Solve a captcha on the current Phantom browser page (via RuCaptcha)"},{"id":"PhantomBrowserController_setProxy","method":"PUT","path":"/api/phantom-browser/profiles/{id}/proxy","summary":"Set the proxy configuration on a Phantom browser profile"},{"id":"PhantomBrowserController_removeProxy","method":"DELETE","path":"/api/phantom-browser/profiles/{id}/proxy","summary":"Remove the proxy configuration from a Phantom browser profile"},{"id":"PhantomBrowserController_testProxy","method":"POST","path":"/api/phantom-browser/profiles/{id}/proxy/test","summary":"Test a Phantom browser profile proxy (launch and report IP)"},{"id":"PhantomBrowserController_listLaunches","method":"GET","path":"/api/phantom-browser/launches","scope":"admin:read","summary":"List Phantom browser profile launches"},{"id":"PhantomBrowserController_listScenarios","method":"GET","path":"/api/phantom-browser/scenarios","scope":"admin:read","summary":"List Phantom browser scenarios"},{"id":"PhantomBrowserController_createScenario","method":"POST","path":"/api/phantom-browser/scenarios","scope":"admin:write","summary":"Create a new Phantom browser scenario"},{"id":"PhantomBrowserController_getScenario","method":"GET","path":"/api/phantom-browser/scenarios/{id}","summary":"Get a single Phantom browser scenario by id"},{"id":"PhantomBrowserController_updateScenario","method":"PUT","path":"/api/phantom-browser/scenarios/{id}","summary":"Update a Phantom browser scenario"},{"id":"PhantomBrowserController_deleteScenario","method":"DELETE","path":"/api/phantom-browser/scenarios/{id}","summary":"Delete a Phantom browser scenario"},{"id":"PhantomBrowserController_listSchedules","method":"GET","path":"/api/phantom-browser/schedules","scope":"admin:read","summary":"List Phantom browser schedules"},{"id":"PhantomBrowserController_createSchedule","method":"POST","path":"/api/phantom-browser/schedules","scope":"admin:write","summary":"Create a new Phantom browser schedule"},{"id":"PhantomBrowserController_updateSchedule","method":"PUT","path":"/api/phantom-browser/schedules/{id}","summary":"Update a Phantom browser schedule"},{"id":"PhantomBrowserController_deleteSchedule","method":"DELETE","path":"/api/phantom-browser/schedules/{id}","summary":"Delete a Phantom browser schedule"},{"id":"PhantomBrowserController_getAdminStats","method":"GET","path":"/api/phantom-browser/admin/stats","scope":"admin:read","summary":"Get Phantom browser admin stats (SUPER only)"},{"id":"PhantomBrowserController_downloadConfig","method":"GET","path":"/api/phantom-browser/download/config","scope":"admin:read","summary":"Download the Phantom desktop client config.json with the user's token"},{"id":"PhantomBrowserDownloadController_syncByToken","method":"POST","path":"/api/phantom-browser/sync","summary":"Sync Phantom desktop client profiles using its token"},{"id":"PhantomBrowserDownloadController_updateCheck","method":"GET","path":"/api/phantom-browser/update/check","summary":"Check for available Phantom client updates"},{"id":"PhantomBrowserDownloadController_updateBundle","method":"GET","path":"/api/phantom-browser/update/bundle","summary":"Download the Phantom client update bundle (gzipped source files)"},{"id":"PhantomBrowserDownloadController_download","method":"GET","path":"/api/phantom-browser/download/{platform}","summary":"Download the Phantom client binary for a given platform"},{"id":"PhantomBrowserDownloadController_receiveLogs","method":"POST","path":"/api/phantom-browser/logs","summary":"Receive logs from the Phantom desktop client"},{"id":"import.templates","method":"GET","path":"/api/import/templates","scope":"import:read","summary":"List available import templates"},{"id":"ImportController_detectTemplate","method":"POST","path":"/api/import/templates/detect","scope":"import:read","summary":"Detect the best matching import template from CSV headers"},{"id":"ImportController_applyTemplate","method":"POST","path":"/api/import/templates/apply","scope":"import:read","summary":"Apply an import template to CSV headers"},{"id":"import.tasks.create","method":"POST","path":"/api/import/tasks","scope":"import:write","summary":"Create a new import task"},{"id":"ImportController_getTask","method":"GET","path":"/api/import/tasks/{id}","summary":"Get an import task by id"},{"id":"ImportController_getLog","method":"GET","path":"/api/import/tasks/{id}/log","summary":"Get the row-level log for an import task"},{"id":"ImportController_getLogCsv","method":"GET","path":"/api/import/tasks/{id}/log/csv","summary":"Download the import task log as CSV"},{"id":"ImportController_cancelTask","method":"POST","path":"/api/import/tasks/{id}/cancel","summary":"Cancel an in-progress import task"},{"id":"ImportController_rollbackTask","method":"POST","path":"/api/import/tasks/{id}/rollback","summary":"Rollback the changes made by an import task"},{"id":"names.decline","method":"POST","path":"/api/names/decline","scope":"utils:read","summary":"Decline a Russian full name (FIO) by grammatical case"},{"id":"NamesController_ping","method":"GET","path":"/api/names/ping","scope":"utils:read","summary":"Ping the names service (health check)"},{"id":"OnDemandController_generate","method":"POST","path":"/api/creative-on-demand/{creativeId}/generate","summary":"Enqueue an on-demand generation request for a creative"},{"id":"OnDemandController_getRequest","method":"GET","path":"/api/creative-on-demand/{creativeId}/requests/{requestId}","summary":"Get a single on-demand request by id"},{"id":"OnDemandController_cancel","method":"POST","path":"/api/creative-on-demand/{creativeId}/requests/{requestId}/cancel","summary":"Cancel an in-flight on-demand request"},{"id":"OnDemandController_list","method":"GET","path":"/api/creative-on-demand/{creativeId}/requests","summary":"List on-demand requests for a creative"},{"id":"OnDemandController_stats","method":"GET","path":"/api/creative-on-demand/{creativeId}/stats","summary":"Get aggregated on-demand stats for a creative"},{"id":"OnDemandController_getQcConfig","method":"GET","path":"/api/creative-on-demand/{creativeId}/qc-config","summary":"Get QC configuration for a creative"},{"id":"OnDemandController_putQcConfig","method":"PUT","path":"/api/creative-on-demand/{creativeId}/qc-config","summary":"Upsert QC configuration for a creative"},{"id":"OnDemandController_resetQcConfig","method":"DELETE","path":"/api/creative-on-demand/{creativeId}/qc-config","summary":"Reset QC configuration to defaults"},{"id":"utils.timezones","method":"GET","path":"/api/utils/timezones","scope":"utils:read","summary":"List IANA timezones with cities, country, offset"},{"id":"utils.tz-lookup","method":"POST","path":"/api/utils/timezone-lookup","scope":"utils:read","summary":"Look up timezone by city or country"},{"id":"BriefsController_getSchemas","method":"GET","path":"/api/briefs/schemas","scope":"briefs:read","summary":"Get available brief JSON schemas"},{"id":"briefs.list","method":"GET","path":"/api/briefs","scope":"briefs:read","summary":"List briefs with pagination, search and active/deleted filters"},{"id":"briefs.create","method":"POST","path":"/api/briefs","scope":"briefs:write","summary":"Create a new brief"},{"id":"BriefsController_findOne","method":"GET","path":"/api/briefs/{id}","summary":"Get a single brief by id"},{"id":"BriefsController_updateMeta","method":"PATCH","path":"/api/briefs/{id}","summary":"Update brief metadata (name, description, status)"},{"id":"BriefsController_softDelete","method":"DELETE","path":"/api/briefs/{id}","summary":"Soft-delete a brief with optional reason"},{"id":"BriefsController_updateContent","method":"PATCH","path":"/api/briefs/{id}/content","summary":"Update brief content body"},{"id":"BriefsController_updateVariables","method":"PATCH","path":"/api/briefs/{id}/variables","summary":"Update brief template variables"},{"id":"BriefsController_updateLocks","method":"PATCH","path":"/api/briefs/{id}/locks","summary":"Update brief section locks"},{"id":"BriefsController_restore","method":"POST","path":"/api/briefs/{id}/restore","summary":"Restore a soft-deleted brief"},{"id":"BriefsController_copy","method":"POST","path":"/api/briefs/{id}/copy","summary":"Duplicate an existing brief"},{"id":"BriefsController_audit","method":"GET","path":"/api/briefs/{id}/audit","summary":"List audit entries for a brief"},{"id":"LandingController_apply","method":"POST","path":"/api/landing/apply","summary":"Submit a public landing-page application form"},{"id":"JobsController_getJob","method":"GET","path":"/api/jobs/{queue}/{id}","summary":"Get the status of any background job by queue + id (Wave 15 unified poll)"}],"guide":{"endpoint":"/api/v1/agent-guide","note":"This API answers like a market expert, not just a REST server. Each MCP/A2A response includes an `_expert` block (hint + next_steps + pitfalls). GET /api/v1/agent-guide for the full capability map and the recommended outreach flow. Send header X-LDM-Guidance: off to suppress the inline layer.","recommended_flow":["1. Audience: ldm_contacts_create / ldm_ContactsController_importStart → gather people into a contact list (ldm_ContactListsController_addContacts). Narrow + relevant beats big.","2. Hygiene FIRST: ldm_EmailVerificationController_verifyBatch — verify addresses before you ever send. Unverified lists bounce, and bounces burn your domain reputation. Non-negotiable.","3. Creative: ldm_creatives_create → ldm_CreativesController_preview → ldm_ContentAnalyzerController_check (spam-trigger words/links) → ldm_CreativesController_startInboxPlacementTest (inbox vs spam BEFORE scaling).","4. Senders: ldm_accounts_create → ldm_EmailAccountsController_checkDns (SPF/DKIM/DMARC) → ldm_EmailAccountsController_testConnection. TWO honest paths, your choice: (a) warm up to raise limits — ldm_EmailAccountsController_warmupStart, takes weeks, the platform does NOT warm for you and it is optional; or (b) skip warm-up and go straight to placement-checked low-volume sends (path 5).","5. Send by MEASUREMENT: send(limit=1), then read placement per provider via control emails — ldm_MailingController_getControlEmailStats + ldm_DeliverabilityController_getMatrix. Spam is a signal, not a failure to hide.","6. React to spam: first swap the relay (ldm_EmailAccountsController_relayHealth / ldm_DeliverabilityController_startCreativeThroughRelay) and re-measure. Still spam on another relay? It is the creative or the volume — fix the copy or send less. Do not touch the rest of the pool.","7. Analytics: set an ACTIVE tracking domain (ldm_TrackingDomainController_create → healthCheck → setDefault) for clean open/click data.","8. Multi-touch + replies: enrol non-responders into a follow-up sequence (ldm_SequencesController_enroll); watch ldm_dialogs_list, classify, and promote opportunities with ldm_DialogsController_createLead."],"docs":{"api_reference":"https://developers.live-direct-marketing.online/api-reference","help_ru":"https://live-direct-marketing.online/help/","help_en":"https://live-direct-marketing.online/help/en/"}},"scopes":["email:send","crm:read","crm:write","dialogs:read","dialogs:write","accounts:read","accounts:write","tasks:read","tasks:write","tasks:create","briefs:read","briefs:write","creatives:read","creatives:write","notifications:read","notifications:write","settings:read","settings:write","ai:read","ai:write","customfields:read","customfields:write","tags:read","tags:write","views:read","views:write","pipelines:read","pipelines:write","rules:read","rules:write","mailing:read","mailing:write","users:read","users:write","keys:read","keys:write","share:read","share:write","legal:read","legal:write","admin:read","admin:write","events:read","events:write","agent:read","agent:write","imap:read","imap:write","suppression:read","suppression:write","stoplist:read","stoplist:write","marking:read","marking:write","linker:read","linker:write","exports:read","exports:write","import:read","import:write","activities:read","activities:write","webhooks:read","webhooks:write","connectors:read","connectors:write","files:read","files:write","icp:read","icp:write","leads:read","leads:write","utils:read","a2a:read","a2a:write"],"signup":{"endpoint":"CRM Settings → API Keys","body":{"note":"Self-serve signup was removed in 2026-05. Log in via the CRM and mint a key."}},"contact":{"billing":"welcome@live-direct-marketing.online","support":"welcome@live-direct-marketing.online"}}