@besales/mcp 0.42.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/instructions/server-instructions.d.ts +1 -1
  2. package/dist/instructions/server-instructions.js +5 -2
  3. package/dist/instructions/server-instructions.js.map +1 -1
  4. package/dist/schemas/mcp-tools.json +837 -25
  5. package/dist/tools/definitions/broadcast-analytics.js +5 -2
  6. package/dist/tools/definitions/broadcast-analytics.js.map +1 -1
  7. package/dist/tools/definitions/broadcast-mailing-variants.d.ts +2 -0
  8. package/dist/tools/definitions/broadcast-mailing-variants.js +12 -3
  9. package/dist/tools/definitions/broadcast-mailing-variants.js.map +1 -1
  10. package/dist/tools/definitions/broadcast-scheduler.d.ts +69 -0
  11. package/dist/tools/definitions/broadcast-scheduler.js +258 -0
  12. package/dist/tools/definitions/broadcast-scheduler.js.map +1 -0
  13. package/dist/tools/definitions/follow-up-setup.d.ts +6 -0
  14. package/dist/tools/definitions/follow-up-setup.js +31 -0
  15. package/dist/tools/definitions/follow-up-setup.js.map +1 -1
  16. package/dist/tools/definitions/follow-up.d.ts +18 -1
  17. package/dist/tools/definitions/follow-up.js +78 -5
  18. package/dist/tools/definitions/follow-up.js.map +1 -1
  19. package/dist/tools/definitions/getcourse-anchor-refresh.d.ts +30 -0
  20. package/dist/tools/definitions/getcourse-anchor-refresh.js +95 -0
  21. package/dist/tools/definitions/getcourse-anchor-refresh.js.map +1 -0
  22. package/dist/tools/definitions/getcourse-cold-welcome.d.ts +8 -0
  23. package/dist/tools/definitions/getcourse-cold-welcome.js +42 -4
  24. package/dist/tools/definitions/getcourse-cold-welcome.js.map +1 -1
  25. package/dist/tools/definitions/getcourse-wave.d.ts +3 -3
  26. package/dist/tools/definitions/getcourse-wave.js +5 -5
  27. package/dist/tools/definitions/getcourse-wave.js.map +1 -1
  28. package/dist/tools/definitions/platform-setup.d.ts +9 -3
  29. package/dist/tools/definitions/platform-setup.js +38 -1
  30. package/dist/tools/definitions/platform-setup.js.map +1 -1
  31. package/dist/tools/definitions/shared.d.ts +14 -0
  32. package/dist/tools/definitions/shared.js +11 -0
  33. package/dist/tools/definitions/shared.js.map +1 -1
  34. package/dist/tools/definitions.d.ts +96 -3
  35. package/dist/tools/definitions.js +4 -0
  36. package/dist/tools/definitions.js.map +1 -1
  37. package/dist/tools/registry-mapping-cases-platform.js +29 -0
  38. package/dist/tools/registry-mapping-cases-platform.js.map +1 -1
  39. package/dist/tools/trigger-action-config.d.ts +49 -0
  40. package/dist/tools/trigger-action-config.js +167 -0
  41. package/dist/tools/trigger-action-config.js.map +1 -0
  42. package/dist/types/api-contract.gen.d.ts +1289 -164
  43. package/package.json +1 -1
@@ -235,7 +235,7 @@ export interface paths {
235
235
  /** @description PKCE S256 challenge — SHA256(code_verifier) base64url-encoded */
236
236
  code_challenge: string;
237
237
  code_challenge_method: "S256";
238
- /** @description Requested scopes: base `mcp:*` plus any subset of the optional scopes, in the canonical order `mcp:platform-setup`, `mcp:funnel-test`, `read:campaigns`, `launch:campaigns`. `besales-mcp connect` always requests the widest string. INVARIANT: a new scope is APPENDED to the optional list — never swapped in for an existing one, or every reconnect silently narrows live keys. */
238
+ /** @description Requested scopes: base `mcp:*` plus any subset of the optional scopes, in the canonical order `mcp:platform-setup`, `mcp:funnel-test`, `read:campaigns`, `launch:campaigns`. `mcp:*` enables PromptHub/ICP/Sandbox/Knowledge tools; `mcp:platform-setup` enables Platform Setup Bridge mutations; `mcp:funnel-test` permits frozen-plan funnel tests that can send real messages; `read:campaigns` covers cold-welcome preview and broadcast reads; `launch:campaigns` covers cold-welcome/broadcast launches. `besales-mcp connect` always requests the widest string. INVARIANT: a new scope is APPENDED to the optional list — never swapped in for an existing one, or every reconnect silently narrows live keys. */
239
239
  scope: "mcp:*" | "mcp:* mcp:platform-setup" | "mcp:* mcp:funnel-test" | "mcp:* mcp:platform-setup mcp:funnel-test" | "mcp:* read:campaigns" | "mcp:* mcp:platform-setup read:campaigns" | "mcp:* mcp:funnel-test read:campaigns" | "mcp:* mcp:platform-setup mcp:funnel-test read:campaigns" | "mcp:* launch:campaigns" | "mcp:* mcp:platform-setup launch:campaigns" | "mcp:* mcp:funnel-test launch:campaigns" | "mcp:* mcp:platform-setup mcp:funnel-test launch:campaigns" | "mcp:* read:campaigns launch:campaigns" | "mcp:* mcp:platform-setup read:campaigns launch:campaigns" | "mcp:* mcp:funnel-test read:campaigns launch:campaigns" | "mcp:* mcp:platform-setup mcp:funnel-test read:campaigns launch:campaigns";
240
240
  };
241
241
  header?: never;
@@ -414,8 +414,12 @@ export interface paths {
414
414
  * @description Public PKCE token endpoint (RFC 7636). Аутентификация — владение одноразовым `code`
415
415
  * (из redirect approve) + `code_verifier`. Code консьюмится атомарно (single-use),
416
416
  * проверяется SHA256(code_verifier) === code_challenge. Только после этого создаётся
417
- * ApiKey (`mcp_<48 chars>`, scopes `mcp:*` + optional `mcp:platform-setup`, expiry 90 days,
417
+ * ApiKey (`mcp_<48 chars>`, scopes из approved гранта, expiry 90 days,
418
418
  * SHA256 hash в `api_keys`) и raw api_key возвращается в теле ответа (НЕ в URL).
419
+ *
420
+ * `dropped_scopes` называет права, которые нёс заменяемый этим реконнектом ключ, а новый
421
+ * не несёт. Сужение набора scope сам connect НЕ ломает — оно всплывает много позже как 403
422
+ * одного эндпоинта, поэтому клиент ОБЯЗАН показать этот список оператору.
419
423
  */
420
424
  post: {
421
425
  parameters: {
@@ -6094,7 +6098,7 @@ export interface paths {
6094
6098
  * @enum {string}
6095
6099
  */
6096
6100
  launchType?: "status" | "board" | "group";
6097
- channels: string[];
6101
+ channels: components["schemas"]["GetCourseTransport"][];
6098
6102
  /** @description Канонический ключ/название бизнес-воронки. Не имя файла, batch/resend или дата конкретного запуска; для этого используется cohortLabel. */
6099
6103
  funnel?: string;
6100
6104
  segment?: string;
@@ -6327,7 +6331,7 @@ export interface paths {
6327
6331
  patch?: never;
6328
6332
  trace?: never;
6329
6333
  };
6330
- "/api/v2/workspaces/{workspaceId}/wazzup-waves/import": {
6334
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome/preview": {
6331
6335
  parameters: {
6332
6336
  query?: never;
6333
6337
  header?: never;
@@ -6337,8 +6341,8 @@ export interface paths {
6337
6341
  get?: never;
6338
6342
  put?: never;
6339
6343
  /**
6340
- * Запуск волны WhatsApp через Wazzup (WABA-шаблон по когорте телефонов)
6341
- * @description v1.5 Increment 24. Без `confirm=true` — dry-run: прогоняется ПОЛНЫЙ preflight (платформа Wazzup активна и с включённым AI, «обрабатывать все входящие», живой WABA-канал, одобренный текстовый шаблон, число значений переменных) и возвращается previewText — ни одно сообщение не отправляется. HTTP-эндпоинт гейтит запуск по `confirm=true`; MCP-тул `besales_wazzup_wave_import` дополнительно требует `explicit_confirmation=true` (это защита от того, чтобы AI-оператор запустил платную рассылку мимоходом — поле потребляется на слое MCP и в тело запроса не передаётся). Каждое маркетинговое сообщение тарифицируется Meta. Политика at-most-once: строка занимается под advisory-локом ДО внешнего вызова, повтор того же шаблона тому же контакту в течение 24 часов пропускается. Scope `mcp:platform-setup`.
6344
+ * Охват рассылки «Первое сообщение» без отправки
6345
+ * @description Read-only. foundContacts — всего под границей; alreadyWelcomed — из них уже получали первое сообщение (оно одноразово НА КОНТАКТ, не на рассылку); totalContacts — сколько ещё может получить. Часть отсеется уже в прогоне (мьют, нет якоря, недостижимость). Аудитория задаётся ЛИБО createdAfter, ЛИБО contacts. Scope `read:campaigns`.
6342
6346
  */
6343
6347
  post: {
6344
6348
  parameters: {
@@ -6351,51 +6355,21 @@ export interface paths {
6351
6355
  };
6352
6356
  requestBody: {
6353
6357
  content: {
6354
- "application/json": {
6355
- /** Format: uuid */
6356
- platformId: string;
6357
- templateGuid: string;
6358
- templateValues?: string[];
6359
- contacts: {
6360
- phone: string;
6361
- name?: string;
6362
- }[];
6363
- funnel?: string;
6364
- segment?: string;
6365
- productCode?: string;
6366
- productName?: string;
6367
- cohortLabel?: string;
6368
- confirm?: boolean;
6369
- };
6358
+ "application/json": components["schemas"]["GetCourseColdWelcomePreviewRequest"];
6370
6359
  };
6371
6360
  };
6372
6361
  responses: {
6373
- /** @description Волна запущена либо выполнен dry-run */
6362
+ /** @description Охват без отправки */
6374
6363
  200: {
6375
6364
  headers: {
6376
6365
  [name: string]: unknown;
6377
6366
  };
6378
6367
  content: {
6379
- "application/json": {
6380
- dryRun: boolean;
6381
- /** Format: uuid */
6382
- jobId?: string;
6383
- totalContacts: number;
6384
- previewText: string;
6385
- message: string;
6386
- rejectedRows?: string[];
6387
- /** @description Некритичные предупреждения preflight — волну не блокируют. Сейчас это мёртвая подписка на статусы доставки (у Wazzup один webhook URI на аккаунт, его мог перезаписать другой сервис): сообщения уйдут и будут оплачены, но доставка не отследится и «дошло» в аналитике останется почти нулевым. */
6388
- warnings?: string[];
6389
- };
6368
+ "application/json": components["schemas"]["GetCourseColdWelcomePreviewResponse"];
6390
6369
  };
6391
6370
  };
6392
- /** @description Непригодные платформа, канал, шаблон или когорта */
6393
- 400: {
6394
- headers: {
6395
- [name: string]: unknown;
6396
- };
6397
- content?: never;
6398
- };
6371
+ 400: components["responses"]["ValidationError"];
6372
+ 404: components["responses"]["NotFound"];
6399
6373
  };
6400
6374
  };
6401
6375
  delete?: never;
@@ -6404,127 +6378,110 @@ export interface paths {
6404
6378
  patch?: never;
6405
6379
  trace?: never;
6406
6380
  };
6407
- "/api/v2/workspaces/{workspaceId}/wazzup-waves/templates/{platformId}": {
6381
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome": {
6408
6382
  parameters: {
6409
6383
  query?: never;
6410
6384
  header?: never;
6411
6385
  path?: never;
6412
6386
  cookie?: never;
6413
6387
  };
6388
+ get?: never;
6389
+ put?: never;
6414
6390
  /**
6415
- * Шаблоны WABA платформы с признаком пригодности для волны
6416
- * @description v1.5 Increment 24. usable=false — шаблон не одобрен Meta либо содержит медиа-заголовок или переменную в URL-кнопке (значения ушли бы не в те слоты). Scope `mcp:platform-setup`.
6391
+ * Запустить рассылку «Первое сообщение» по когорте GetCourse
6392
+ * @description НЕОБРАТИМО: у GetCourse нет идемпотентности, отправку нельзя отозвать. Приветствие одноразово НА КОНТАКТ навсегда. Текст берётся из mailingVariantId ЛИБО message (ровно один источник). Если у рассылки заданы посегментные тексты и segment совпал — уедет текст сегмента, и тогда аудитория обязана быть файловой (contacts): с createdAfter такой запуск отвергается 400, потому что метка сегмента аудиторию не отбирает. Поля сделки штампуются ПОСЛЕ успешной отправки. Scope `launch:campaigns`.
6417
6393
  */
6418
- get: {
6394
+ post: {
6419
6395
  parameters: {
6420
6396
  query?: never;
6421
6397
  header?: never;
6422
6398
  path: {
6423
6399
  workspaceId: components["parameters"]["WorkspaceIdPath"];
6424
- platformId: string;
6425
6400
  };
6426
6401
  cookie?: never;
6427
6402
  };
6428
- requestBody?: never;
6403
+ requestBody: {
6404
+ content: {
6405
+ "application/json": components["schemas"]["GetCourseColdWelcomeLaunchRequest"];
6406
+ };
6407
+ };
6429
6408
  responses: {
6430
- /** @description Список шаблонов */
6409
+ /** @description Рассылка поставлена в очередь */
6431
6410
  200: {
6432
6411
  headers: {
6433
6412
  [name: string]: unknown;
6434
6413
  };
6435
6414
  content: {
6436
- "application/json": {
6437
- templateGuid: string;
6438
- title: string;
6439
- status: string;
6440
- bodyText: string;
6441
- variableCount: number;
6442
- usable: boolean;
6443
- unsupportedReasons?: string[];
6444
- }[];
6415
+ "application/json": components["schemas"]["GetCourseColdWelcomeLaunchResponse"];
6416
+ };
6417
+ };
6418
+ 400: components["responses"]["ValidationError"];
6419
+ 404: components["responses"]["NotFound"];
6420
+ /** @description В воркспейсе уже идёт задача импорта */
6421
+ 409: {
6422
+ headers: {
6423
+ [name: string]: unknown;
6424
+ };
6425
+ content: {
6426
+ "application/json": components["schemas"]["ErrorResponse"];
6445
6427
  };
6446
6428
  };
6447
6429
  };
6448
6430
  };
6449
- put?: never;
6450
- post?: never;
6451
6431
  delete?: never;
6452
6432
  options?: never;
6453
6433
  head?: never;
6454
6434
  patch?: never;
6455
6435
  trace?: never;
6456
6436
  };
6457
- "/api/v2/workspaces/{workspaceId}/wazzup-waves/{jobId}": {
6437
+ "/api/v2/workspaces/{workspaceId}/getcourse-anchor-refresh/preview": {
6458
6438
  parameters: {
6459
6439
  query?: never;
6460
6440
  header?: never;
6461
6441
  path?: never;
6462
6442
  cookie?: never;
6463
6443
  };
6444
+ get?: never;
6445
+ put?: never;
6464
6446
  /**
6465
- * Статус волны WhatsApp
6466
- * @description v1.5 Increment 24. skipped — сознательные пропуски (стоп-бот, ожидание оператора, недавний повтор), НЕ ошибки. unknownOutcome — строки, где отправка началась, но ответ Wazzup не дошёл; автоматически они не переотправляются. Scope `mcp:platform-setup`.
6447
+ * Что перепишет перечитывание календарных якорей
6448
+ * @description Read-only и БЕЗ обращений к школе — считает по базе. contactsMatched — сколько контактов в отборе; withoutPinnedDeal — скольким прогон откажет (без пина читалась бы произвольная сделка, и верная дата была бы затёрта чужой); currentValues — какие значения якорей они несут СЕЙЧАС. НОВЫЕ значения предпросмотр не знает: для этого надо прочитать все сделки, то есть выполнить сам прогон. Scope `read:campaigns`.
6467
6449
  */
6468
- get: {
6450
+ post: {
6469
6451
  parameters: {
6470
6452
  query?: never;
6471
6453
  header?: never;
6472
6454
  path: {
6473
6455
  workspaceId: components["parameters"]["WorkspaceIdPath"];
6474
- jobId: string;
6475
6456
  };
6476
6457
  cookie?: never;
6477
6458
  };
6478
- requestBody?: never;
6459
+ requestBody: {
6460
+ content: {
6461
+ "application/json": components["schemas"]["GetCourseAnchorRefreshRequest"];
6462
+ };
6463
+ };
6479
6464
  responses: {
6480
- /** @description Статус волны */
6465
+ /** @description Охват перечитывания без записи */
6481
6466
  200: {
6482
6467
  headers: {
6483
6468
  [name: string]: unknown;
6484
6469
  };
6485
6470
  content: {
6486
- "application/json": {
6487
- jobId: string;
6488
- /** @enum {string} */
6489
- status: "PROCESSING" | "COMPLETED";
6490
- totalRows: number;
6491
- processedRows: number;
6492
- sent: number;
6493
- failed: number;
6494
- skipped: number;
6495
- unknownOutcome: number;
6496
- /** @description Подтверждено вебхуком WhatsApp. Живёт ОТДЕЛЬНО от sent: sent означает лишь что Wazzup принял сообщение. Взаимоисключающе с deliveryFailed. */
6497
- delivered?: number;
6498
- /** @description Подмножество delivered — получатель открыл сообщение */
6499
- read?: number;
6500
- /** @description Отказ доставки по данным WhatsApp. НЕ меняет исход самой отправки: status строки описывает результат нашего вызова, а не доставку. */
6501
- deliveryFailed?: number;
6502
- /** @description Разбивка отказов по кодам ошибок Wazzup */
6503
- deliveryErrors?: {
6504
- [key: string]: number;
6505
- };
6506
- errors?: string[];
6507
- };
6471
+ "application/json": components["schemas"]["GetCourseAnchorRefreshPreviewResponse"];
6508
6472
  };
6509
6473
  };
6510
- /** @description Волна не найдена в этом рабочем пространстве */
6511
- 404: {
6512
- headers: {
6513
- [name: string]: unknown;
6514
- };
6515
- content?: never;
6516
- };
6474
+ 400: components["responses"]["ValidationError"];
6475
+ 404: components["responses"]["NotFound"];
6517
6476
  };
6518
6477
  };
6519
- put?: never;
6520
- post?: never;
6521
6478
  delete?: never;
6522
6479
  options?: never;
6523
6480
  head?: never;
6524
6481
  patch?: never;
6525
6482
  trace?: never;
6526
6483
  };
6527
- "/api/v2/platforms/{platformId}/agents/{agentId}/tools": {
6484
+ "/api/v2/workspaces/{workspaceId}/getcourse-anchor-refresh": {
6528
6485
  parameters: {
6529
6486
  query?: never;
6530
6487
  header?: never;
@@ -6533,40 +6490,45 @@ export interface paths {
6533
6490
  };
6534
6491
  get?: never;
6535
6492
  put?: never;
6536
- post?: never;
6537
- delete?: never;
6538
- options?: never;
6539
- head?: never;
6540
- /** Patch agent tool bindings without deleting omitted tools */
6541
- patch: {
6493
+ /**
6494
+ * Перечитать календарные якоря контактов из запинённой сделки
6495
+ * @description Единственный способ донести ПЕРЕНЕСЁННУЮ дату эфира: автоматический добор якоря — set-if-absent и к заполненному значению не возвращается, поэтому «Первое сообщение» будет возвращать SKIPPED_ANCHOR_IN_PAST, сколько его ни запускай. Перечитываются ТОЛЬКО якоря включённых календарных цепочек площадки и ТОЛЬКО с ЗАПИНЁННОЙ сделки; переменные ветвления не трогаются. Прогресс цепочек НЕ откатывается: ушедшие касания остаются ушедшими, перепланируются только не ушедшие. Каждое изменение пишется строкой audit_logs (entityType=ChatUser, action=GETCOURSE_ANCHOR_REFRESH) с прежним и новым значением. Прогон асинхронный — ответ подтверждает старт. Scope `launch:campaigns`.
6496
+ */
6497
+ post: {
6542
6498
  parameters: {
6543
6499
  query?: never;
6544
6500
  header?: never;
6545
6501
  path: {
6546
- platformId: components["parameters"]["PlatformIdPath"];
6547
- agentId: components["parameters"]["AgentIdPath"];
6502
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6548
6503
  };
6549
6504
  cookie?: never;
6550
6505
  };
6551
6506
  requestBody: {
6552
6507
  content: {
6553
- "application/json": components["schemas"]["AgentToolsPatchRequest"];
6508
+ "application/json": components["schemas"]["GetCourseAnchorRefreshRequest"];
6554
6509
  };
6555
6510
  };
6556
6511
  responses: {
6557
- 200: {
6512
+ /** @description Прогон принят (либо отказ с причиной в полях ответа) */
6513
+ 202: {
6558
6514
  headers: {
6559
6515
  [name: string]: unknown;
6560
6516
  };
6561
6517
  content: {
6562
- "application/json": components["schemas"]["PlatformSetupMutationResult"];
6518
+ "application/json": components["schemas"]["GetCourseAnchorRefreshStartResponse"];
6563
6519
  };
6564
6520
  };
6521
+ 400: components["responses"]["ValidationError"];
6522
+ 404: components["responses"]["NotFound"];
6565
6523
  };
6566
6524
  };
6525
+ delete?: never;
6526
+ options?: never;
6527
+ head?: never;
6528
+ patch?: never;
6567
6529
  trace?: never;
6568
6530
  };
6569
- "/api/v2/platforms/{platformId}/router": {
6531
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome/batch": {
6570
6532
  parameters: {
6571
6533
  query?: never;
6572
6534
  header?: never;
@@ -6575,155 +6537,822 @@ export interface paths {
6575
6537
  };
6576
6538
  get?: never;
6577
6539
  put?: never;
6578
- post?: never;
6579
- delete?: never;
6580
- options?: never;
6581
- head?: never;
6582
- /** Patch router metadata/additionalPrompt only */
6583
- patch: {
6540
+ /**
6541
+ * Запустить пакет сегментов «Первого сообщения»
6542
+ * @description НЕОБРАТИМО. До 10 сегментов, у каждого свой список контактов, свои метки и свои поля сделки. Идут ПО ОЧЕРЕДИ: задачи импорта в воркспейсе не выполняются параллельно. Весь пакет проверяется ДО первой отправки — сегмент без текста отменяет пакет целиком. Один сегмент МОЖЕТ идти несколькими блоками (разбивка по продуктам через funnel/productCode); запрещено пересечение СПИСКОВ контактов между блоками, а не совпадение меток. Scope `launch:campaigns`.
6543
+ */
6544
+ post: {
6584
6545
  parameters: {
6585
6546
  query?: never;
6586
6547
  header?: never;
6587
6548
  path: {
6588
- platformId: components["parameters"]["PlatformIdPath"];
6549
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6589
6550
  };
6590
6551
  cookie?: never;
6591
6552
  };
6592
6553
  requestBody: {
6593
6554
  content: {
6594
- "application/json": components["schemas"]["RouterPatchRequest"];
6555
+ "application/json": components["schemas"]["GetCourseColdWelcomeBatchRequest"];
6595
6556
  };
6596
6557
  };
6597
6558
  responses: {
6559
+ /** @description Пакет поставлен в очередь целиком */
6598
6560
  200: {
6599
6561
  headers: {
6600
6562
  [name: string]: unknown;
6601
6563
  };
6602
6564
  content: {
6603
- "application/json": components["schemas"]["PlatformSetupMutationResult"];
6565
+ "application/json": components["schemas"]["GetCourseColdWelcomeBatchResponse"];
6566
+ };
6567
+ };
6568
+ 400: components["responses"]["ValidationError"];
6569
+ 404: components["responses"]["NotFound"];
6570
+ /** @description В воркспейсе уже идёт пакет */
6571
+ 409: {
6572
+ headers: {
6573
+ [name: string]: unknown;
6574
+ };
6575
+ content: {
6576
+ "application/json": components["schemas"]["ErrorResponse"];
6604
6577
  };
6605
6578
  };
6606
6579
  };
6607
6580
  };
6581
+ delete?: never;
6582
+ options?: never;
6583
+ head?: never;
6584
+ patch?: never;
6608
6585
  trace?: never;
6609
6586
  };
6610
- "/api/v2/platforms/{platformId}/router/routing-rules": {
6587
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome/batch/{batchId}": {
6611
6588
  parameters: {
6612
6589
  query?: never;
6613
6590
  header?: never;
6614
6591
  path?: never;
6615
6592
  cookie?: never;
6616
6593
  };
6617
- get?: never;
6618
- put?: never;
6619
- /** Create one granular routing rule */
6620
- post: {
6594
+ /**
6595
+ * Состояние пакета сегментов
6596
+ * @description Агрегат state плюс разбивка segments[] со своим статусом, importJobId и причиной отказа у каждого. stalled=true означает доказанный обрыв драйвера (протух пульс) — остаток поднимается через resume. Scope `read:campaigns`.
6597
+ */
6598
+ get: {
6621
6599
  parameters: {
6622
6600
  query?: never;
6623
6601
  header?: never;
6624
6602
  path: {
6625
- platformId: components["parameters"]["PlatformIdPath"];
6603
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6604
+ batchId: components["parameters"]["ColdWelcomeBatchIdPath"];
6626
6605
  };
6627
6606
  cookie?: never;
6628
6607
  };
6629
- requestBody: {
6630
- content: {
6631
- "application/json": components["schemas"]["RoutingRuleUpsertRequest"];
6632
- };
6633
- };
6608
+ requestBody?: never;
6634
6609
  responses: {
6635
- 201: {
6610
+ /** @description Состояние пакета */
6611
+ 200: {
6636
6612
  headers: {
6637
6613
  [name: string]: unknown;
6638
6614
  };
6639
6615
  content: {
6640
- "application/json": components["schemas"]["PlatformSetupMutationResult"];
6616
+ "application/json": components["schemas"]["GetCourseColdWelcomeBatchStatus"];
6641
6617
  };
6642
6618
  };
6619
+ 404: components["responses"]["NotFound"];
6643
6620
  };
6644
6621
  };
6622
+ put?: never;
6623
+ post?: never;
6645
6624
  delete?: never;
6646
6625
  options?: never;
6647
6626
  head?: never;
6648
- /** Patch one granular routing rule; no bulk router replace */
6649
- patch: {
6627
+ patch?: never;
6628
+ trace?: never;
6629
+ };
6630
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome/batch/{batchId}/resume": {
6631
+ parameters: {
6632
+ query?: never;
6633
+ header?: never;
6634
+ path?: never;
6635
+ cookie?: never;
6636
+ };
6637
+ get?: never;
6638
+ put?: never;
6639
+ /**
6640
+ * Возобновить остаток пакета после обрыва драйвера
6641
+ * @description Разрешено ТОЛЬКО пакету, чей статус подтвердил обрыв (stalled). Источник текста хранится в плане — списки контактов пересобирать не нужно. Повтора отправки не будет: приветствие одноразово на контакт. Scope `launch:campaigns`.
6642
+ */
6643
+ post: {
6650
6644
  parameters: {
6651
6645
  query?: never;
6652
6646
  header?: never;
6653
6647
  path: {
6654
- platformId: components["parameters"]["PlatformIdPath"];
6648
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6649
+ batchId: components["parameters"]["ColdWelcomeBatchIdPath"];
6655
6650
  };
6656
6651
  cookie?: never;
6657
6652
  };
6658
- requestBody: {
6659
- content: {
6660
- "application/json": components["schemas"]["RoutingRuleUpsertRequest"];
6661
- };
6662
- };
6653
+ requestBody?: never;
6663
6654
  responses: {
6655
+ /** @description Остаток пакета поднят */
6664
6656
  200: {
6665
6657
  headers: {
6666
6658
  [name: string]: unknown;
6667
6659
  };
6668
6660
  content: {
6669
- "application/json": components["schemas"]["PlatformSetupMutationResult"];
6661
+ "application/json": {
6662
+ /** @description Сегментов осталось в очереди */
6663
+ pending: number;
6664
+ };
6665
+ };
6666
+ };
6667
+ 404: components["responses"]["NotFound"];
6668
+ /** @description Пакет не в состоянии обрыва — возобновлять нечего */
6669
+ 409: {
6670
+ headers: {
6671
+ [name: string]: unknown;
6672
+ };
6673
+ content: {
6674
+ "application/json": components["schemas"]["ErrorResponse"];
6670
6675
  };
6671
6676
  };
6672
6677
  };
6673
6678
  };
6679
+ delete?: never;
6680
+ options?: never;
6681
+ head?: never;
6682
+ patch?: never;
6674
6683
  trace?: never;
6675
6684
  };
6676
- "/api/v2/platforms/{platformId}/dialogue-audit/config": {
6685
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome/batch/{batchId}/cancel": {
6677
6686
  parameters: {
6678
6687
  query?: never;
6679
6688
  header?: never;
6680
6689
  path?: never;
6681
6690
  cookie?: never;
6682
6691
  };
6692
+ get?: never;
6693
+ put?: never;
6683
6694
  /**
6684
- * Reviewer settings of the channel (read-only)
6685
- * @description `isConfigured=false` means the config row does not exist yet and the returned values are defaults. GET never creates anything. Writing settings is intentionally not exposed to MCP.
6695
+ * Отменить остаток пакета
6696
+ * @description Действует на не начатые сегменты и идущую задачу. Уже отправленное не отзывается. Scope `launch:campaigns`.
6686
6697
  */
6687
- get: {
6698
+ post: {
6688
6699
  parameters: {
6689
6700
  query?: never;
6690
6701
  header?: never;
6691
6702
  path: {
6692
- platformId: components["parameters"]["PlatformIdPath"];
6703
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6704
+ batchId: components["parameters"]["ColdWelcomeBatchIdPath"];
6693
6705
  };
6694
6706
  cookie?: never;
6695
6707
  };
6696
6708
  requestBody?: never;
6697
6709
  responses: {
6710
+ /** @description Остаток помечен отменённым */
6698
6711
  200: {
6699
6712
  headers: {
6700
6713
  [name: string]: unknown;
6701
6714
  };
6702
6715
  content: {
6703
- "application/json": components["schemas"]["DialogueAuditConfig"];
6716
+ "application/json": {
6717
+ /** @description Сколько сегментов снято */
6718
+ cancelled: number;
6719
+ };
6704
6720
  };
6705
6721
  };
6722
+ 404: components["responses"]["NotFound"];
6706
6723
  };
6707
6724
  };
6708
- put?: never;
6709
- post?: never;
6710
6725
  delete?: never;
6711
6726
  options?: never;
6712
6727
  head?: never;
6713
6728
  patch?: never;
6714
6729
  trace?: never;
6715
6730
  };
6716
- "/api/v2/platforms/{platformId}/dialogue-audit/runs": {
6731
+ "/api/v2/workspaces/{workspaceId}/getcourse-cold-welcome/{jobId}/cancel": {
6717
6732
  parameters: {
6718
6733
  query?: never;
6719
6734
  header?: never;
6720
6735
  path?: never;
6721
6736
  cookie?: never;
6722
6737
  };
6723
- /** Reviewer run history (cursor pagination) */
6724
- get: {
6725
- parameters: {
6726
- query?: {
6738
+ get?: never;
6739
+ put?: never;
6740
+ /**
6741
+ * Остановить идущую рассылку «Первое сообщение»
6742
+ * @description Действует на остаток когорты в пределах ~10 секунд; уже отправленное не отзывается. Scope `launch:campaigns`.
6743
+ */
6744
+ post: {
6745
+ parameters: {
6746
+ query?: never;
6747
+ header?: never;
6748
+ path: {
6749
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6750
+ jobId: components["parameters"]["ColdWelcomeJobIdPath"];
6751
+ };
6752
+ cookie?: never;
6753
+ };
6754
+ requestBody?: never;
6755
+ responses: {
6756
+ /** @description Остановка запрошена */
6757
+ 200: {
6758
+ headers: {
6759
+ [name: string]: unknown;
6760
+ };
6761
+ content: {
6762
+ "application/json": {
6763
+ /** @enum {boolean} */
6764
+ cancelRequested: true;
6765
+ };
6766
+ };
6767
+ };
6768
+ 404: components["responses"]["NotFound"];
6769
+ };
6770
+ };
6771
+ delete?: never;
6772
+ options?: never;
6773
+ head?: never;
6774
+ patch?: never;
6775
+ trace?: never;
6776
+ };
6777
+ "/api/v2/workspaces/{workspaceId}/chat-users/import/getcourse-contacts": {
6778
+ parameters: {
6779
+ query?: never;
6780
+ header?: never;
6781
+ path?: never;
6782
+ cookie?: never;
6783
+ };
6784
+ get?: never;
6785
+ put?: never;
6786
+ /**
6787
+ * Импорт контактов GetCourse списком (без файла)
6788
+ * @description Заводит или обновляет контакты GetCourse в базе платформы, чтобы по ним можно было запускать «Нашу отправку». НИЧЕГО НЕ ОТПРАВЛЯЕТ. Нужен ровно тогда, когда preview показал notInBase > 0: отправке нужен ChatUser, иначе контакт получает исход SKIPPED_NOT_IN_BASE. Матчинг существующих — по contactId (getcourse_user_id). Максимум 5000 контактов, идёт фоном; прогресс — GET /chat-users/import/jobs/{jobId}. Гейт «один активный импорт на воркспейс» общий с волнами и пакетами. Ключи строк — имена колонок экспорта GetCourse: их читает тот же разбор, что и файл. Scope `launch:campaigns`, а НЕ `mcp:platform-setup` — тот разворачивается в право настройки платформы.
6789
+ */
6790
+ post: {
6791
+ parameters: {
6792
+ query?: never;
6793
+ header?: never;
6794
+ path: {
6795
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6796
+ };
6797
+ cookie?: never;
6798
+ };
6799
+ requestBody: {
6800
+ content: {
6801
+ "application/json": components["schemas"]["GetCourseContactsImportRequest"];
6802
+ };
6803
+ };
6804
+ responses: {
6805
+ /** @description Импорт запущен либо строки отбракованы разбором */
6806
+ 200: {
6807
+ headers: {
6808
+ [name: string]: unknown;
6809
+ };
6810
+ content: {
6811
+ "application/json": components["schemas"]["GetCourseContactsImportResponse"];
6812
+ };
6813
+ };
6814
+ 400: components["responses"]["ValidationError"];
6815
+ 404: components["responses"]["NotFound"];
6816
+ /** @description В воркспейсе уже идёт задача импорта */
6817
+ 409: {
6818
+ headers: {
6819
+ [name: string]: unknown;
6820
+ };
6821
+ content: {
6822
+ "application/json": components["schemas"]["ErrorResponse"];
6823
+ };
6824
+ };
6825
+ };
6826
+ };
6827
+ delete?: never;
6828
+ options?: never;
6829
+ head?: never;
6830
+ patch?: never;
6831
+ trace?: never;
6832
+ };
6833
+ "/api/v2/workspaces/{workspaceId}/broadcasts/launches": {
6834
+ parameters: {
6835
+ query?: never;
6836
+ header?: never;
6837
+ path?: never;
6838
+ cookie?: never;
6839
+ };
6840
+ /**
6841
+ * История запусков — наша отправка и волны по файлу одним списком
6842
+ * @description Scope `read:campaigns`.
6843
+ */
6844
+ get: {
6845
+ parameters: {
6846
+ query?: {
6847
+ mailingVariantId?: string;
6848
+ limit?: number;
6849
+ };
6850
+ header?: never;
6851
+ path: {
6852
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6853
+ };
6854
+ cookie?: never;
6855
+ };
6856
+ requestBody?: never;
6857
+ responses: {
6858
+ /** @description Страница истории запусков */
6859
+ 200: {
6860
+ headers: {
6861
+ [name: string]: unknown;
6862
+ };
6863
+ content: {
6864
+ "application/json": components["schemas"]["BroadcastLaunchesPage"];
6865
+ };
6866
+ };
6867
+ };
6868
+ };
6869
+ put?: never;
6870
+ post?: never;
6871
+ delete?: never;
6872
+ options?: never;
6873
+ head?: never;
6874
+ patch?: never;
6875
+ trace?: never;
6876
+ };
6877
+ "/api/v2/workspaces/{workspaceId}/broadcasts/variants-summary": {
6878
+ parameters: {
6879
+ query?: never;
6880
+ header?: never;
6881
+ path?: never;
6882
+ cookie?: never;
6883
+ };
6884
+ /**
6885
+ * Сводка по каждой рассылке — запусков, отправлено, последний запуск
6886
+ * @description Scope `read:campaigns`.
6887
+ */
6888
+ get: {
6889
+ parameters: {
6890
+ query?: never;
6891
+ header?: never;
6892
+ path: {
6893
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6894
+ };
6895
+ cookie?: never;
6896
+ };
6897
+ requestBody?: never;
6898
+ responses: {
6899
+ /** @description Сводка по рассылкам */
6900
+ 200: {
6901
+ headers: {
6902
+ [name: string]: unknown;
6903
+ };
6904
+ content: {
6905
+ "application/json": components["schemas"]["BroadcastVariantSummary"][];
6906
+ };
6907
+ };
6908
+ };
6909
+ };
6910
+ put?: never;
6911
+ post?: never;
6912
+ delete?: never;
6913
+ options?: never;
6914
+ head?: never;
6915
+ patch?: never;
6916
+ trace?: never;
6917
+ };
6918
+ "/api/v2/workspaces/{workspaceId}/broadcasts/label-suggestions": {
6919
+ parameters: {
6920
+ query?: never;
6921
+ header?: never;
6922
+ path?: never;
6923
+ cookie?: never;
6924
+ };
6925
+ /**
6926
+ * Метки прошлых запусков — чтобы переиспользовать значения, а не плодить опечатки
6927
+ * @description Scope `read:campaigns`.
6928
+ */
6929
+ get: {
6930
+ parameters: {
6931
+ query?: never;
6932
+ header?: never;
6933
+ path: {
6934
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6935
+ };
6936
+ cookie?: never;
6937
+ };
6938
+ requestBody?: never;
6939
+ responses: {
6940
+ /** @description Ранее использованные метки */
6941
+ 200: {
6942
+ headers: {
6943
+ [name: string]: unknown;
6944
+ };
6945
+ content: {
6946
+ "application/json": components["schemas"]["BroadcastLabelSuggestions"];
6947
+ };
6948
+ };
6949
+ };
6950
+ };
6951
+ put?: never;
6952
+ post?: never;
6953
+ delete?: never;
6954
+ options?: never;
6955
+ head?: never;
6956
+ patch?: never;
6957
+ trace?: never;
6958
+ };
6959
+ "/api/v2/workspaces/{workspaceId}/wazzup-waves/import": {
6960
+ parameters: {
6961
+ query?: never;
6962
+ header?: never;
6963
+ path?: never;
6964
+ cookie?: never;
6965
+ };
6966
+ get?: never;
6967
+ put?: never;
6968
+ /**
6969
+ * Запуск волны WhatsApp через Wazzup (WABA-шаблон по когорте телефонов)
6970
+ * @description v1.5 Increment 24. Без `confirm=true` — dry-run: прогоняется ПОЛНЫЙ preflight (платформа Wazzup активна и с включённым AI, «обрабатывать все входящие», живой WABA-канал, одобренный текстовый шаблон, число значений переменных) и возвращается previewText — ни одно сообщение не отправляется. HTTP-эндпоинт гейтит запуск по `confirm=true`; MCP-тул `besales_wazzup_wave_import` дополнительно требует `explicit_confirmation=true` (это защита от того, чтобы AI-оператор запустил платную рассылку мимоходом — поле потребляется на слое MCP и в тело запроса не передаётся). Каждое маркетинговое сообщение тарифицируется Meta. Политика at-most-once: строка занимается под advisory-локом ДО внешнего вызова, повтор того же шаблона тому же контакту в течение 24 часов пропускается. Scope `mcp:platform-setup`.
6971
+ */
6972
+ post: {
6973
+ parameters: {
6974
+ query?: never;
6975
+ header?: never;
6976
+ path: {
6977
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
6978
+ };
6979
+ cookie?: never;
6980
+ };
6981
+ requestBody: {
6982
+ content: {
6983
+ "application/json": {
6984
+ /** Format: uuid */
6985
+ platformId: string;
6986
+ templateGuid: string;
6987
+ templateValues?: string[];
6988
+ contacts: {
6989
+ phone: string;
6990
+ name?: string;
6991
+ }[];
6992
+ funnel?: string;
6993
+ segment?: string;
6994
+ productCode?: string;
6995
+ productName?: string;
6996
+ cohortLabel?: string;
6997
+ confirm?: boolean;
6998
+ };
6999
+ };
7000
+ };
7001
+ responses: {
7002
+ /** @description Волна запущена либо выполнен dry-run */
7003
+ 200: {
7004
+ headers: {
7005
+ [name: string]: unknown;
7006
+ };
7007
+ content: {
7008
+ "application/json": {
7009
+ dryRun: boolean;
7010
+ /** Format: uuid */
7011
+ jobId?: string;
7012
+ totalContacts: number;
7013
+ previewText: string;
7014
+ message: string;
7015
+ rejectedRows?: string[];
7016
+ /** @description Некритичные предупреждения preflight — волну не блокируют. Сейчас это мёртвая подписка на статусы доставки (у Wazzup один webhook URI на аккаунт, его мог перезаписать другой сервис): сообщения уйдут и будут оплачены, но доставка не отследится и «дошло» в аналитике останется почти нулевым. */
7017
+ warnings?: string[];
7018
+ };
7019
+ };
7020
+ };
7021
+ /** @description Непригодные платформа, канал, шаблон или когорта */
7022
+ 400: {
7023
+ headers: {
7024
+ [name: string]: unknown;
7025
+ };
7026
+ content?: never;
7027
+ };
7028
+ };
7029
+ };
7030
+ delete?: never;
7031
+ options?: never;
7032
+ head?: never;
7033
+ patch?: never;
7034
+ trace?: never;
7035
+ };
7036
+ "/api/v2/workspaces/{workspaceId}/wazzup-waves/templates/{platformId}": {
7037
+ parameters: {
7038
+ query?: never;
7039
+ header?: never;
7040
+ path?: never;
7041
+ cookie?: never;
7042
+ };
7043
+ /**
7044
+ * Шаблоны WABA платформы с признаком пригодности для волны
7045
+ * @description v1.5 Increment 24. usable=false — шаблон не одобрен Meta либо содержит медиа-заголовок или переменную в URL-кнопке (значения ушли бы не в те слоты). Scope `mcp:platform-setup`.
7046
+ */
7047
+ get: {
7048
+ parameters: {
7049
+ query?: never;
7050
+ header?: never;
7051
+ path: {
7052
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
7053
+ platformId: string;
7054
+ };
7055
+ cookie?: never;
7056
+ };
7057
+ requestBody?: never;
7058
+ responses: {
7059
+ /** @description Список шаблонов */
7060
+ 200: {
7061
+ headers: {
7062
+ [name: string]: unknown;
7063
+ };
7064
+ content: {
7065
+ "application/json": {
7066
+ templateGuid: string;
7067
+ title: string;
7068
+ status: string;
7069
+ bodyText: string;
7070
+ variableCount: number;
7071
+ usable: boolean;
7072
+ unsupportedReasons?: string[];
7073
+ }[];
7074
+ };
7075
+ };
7076
+ };
7077
+ };
7078
+ put?: never;
7079
+ post?: never;
7080
+ delete?: never;
7081
+ options?: never;
7082
+ head?: never;
7083
+ patch?: never;
7084
+ trace?: never;
7085
+ };
7086
+ "/api/v2/workspaces/{workspaceId}/wazzup-waves/{jobId}": {
7087
+ parameters: {
7088
+ query?: never;
7089
+ header?: never;
7090
+ path?: never;
7091
+ cookie?: never;
7092
+ };
7093
+ /**
7094
+ * Статус волны WhatsApp
7095
+ * @description v1.5 Increment 24. skipped — сознательные пропуски (стоп-бот, ожидание оператора, недавний повтор), НЕ ошибки. unknownOutcome — строки, где отправка началась, но ответ Wazzup не дошёл; автоматически они не переотправляются. Scope `mcp:platform-setup`.
7096
+ */
7097
+ get: {
7098
+ parameters: {
7099
+ query?: never;
7100
+ header?: never;
7101
+ path: {
7102
+ workspaceId: components["parameters"]["WorkspaceIdPath"];
7103
+ jobId: string;
7104
+ };
7105
+ cookie?: never;
7106
+ };
7107
+ requestBody?: never;
7108
+ responses: {
7109
+ /** @description Статус волны */
7110
+ 200: {
7111
+ headers: {
7112
+ [name: string]: unknown;
7113
+ };
7114
+ content: {
7115
+ "application/json": {
7116
+ jobId: string;
7117
+ /** @enum {string} */
7118
+ status: "PROCESSING" | "COMPLETED";
7119
+ totalRows: number;
7120
+ processedRows: number;
7121
+ sent: number;
7122
+ failed: number;
7123
+ skipped: number;
7124
+ unknownOutcome: number;
7125
+ /** @description Подтверждено вебхуком WhatsApp. Живёт ОТДЕЛЬНО от sent: sent означает лишь что Wazzup принял сообщение. Взаимоисключающе с deliveryFailed. */
7126
+ delivered?: number;
7127
+ /** @description Подмножество delivered — получатель открыл сообщение */
7128
+ read?: number;
7129
+ /** @description Отказ доставки по данным WhatsApp. НЕ меняет исход самой отправки: status строки описывает результат нашего вызова, а не доставку. */
7130
+ deliveryFailed?: number;
7131
+ /** @description Разбивка отказов по кодам ошибок Wazzup */
7132
+ deliveryErrors?: {
7133
+ [key: string]: number;
7134
+ };
7135
+ errors?: string[];
7136
+ };
7137
+ };
7138
+ };
7139
+ /** @description Волна не найдена в этом рабочем пространстве */
7140
+ 404: {
7141
+ headers: {
7142
+ [name: string]: unknown;
7143
+ };
7144
+ content?: never;
7145
+ };
7146
+ };
7147
+ };
7148
+ put?: never;
7149
+ post?: never;
7150
+ delete?: never;
7151
+ options?: never;
7152
+ head?: never;
7153
+ patch?: never;
7154
+ trace?: never;
7155
+ };
7156
+ "/api/v2/platforms/{platformId}/agents/{agentId}/tools": {
7157
+ parameters: {
7158
+ query?: never;
7159
+ header?: never;
7160
+ path?: never;
7161
+ cookie?: never;
7162
+ };
7163
+ get?: never;
7164
+ put?: never;
7165
+ post?: never;
7166
+ delete?: never;
7167
+ options?: never;
7168
+ head?: never;
7169
+ /** Patch agent tool bindings without deleting omitted tools */
7170
+ patch: {
7171
+ parameters: {
7172
+ query?: never;
7173
+ header?: never;
7174
+ path: {
7175
+ platformId: components["parameters"]["PlatformIdPath"];
7176
+ agentId: components["parameters"]["AgentIdPath"];
7177
+ };
7178
+ cookie?: never;
7179
+ };
7180
+ requestBody: {
7181
+ content: {
7182
+ "application/json": components["schemas"]["AgentToolsPatchRequest"];
7183
+ };
7184
+ };
7185
+ responses: {
7186
+ 200: {
7187
+ headers: {
7188
+ [name: string]: unknown;
7189
+ };
7190
+ content: {
7191
+ "application/json": components["schemas"]["PlatformSetupMutationResult"];
7192
+ };
7193
+ };
7194
+ };
7195
+ };
7196
+ trace?: never;
7197
+ };
7198
+ "/api/v2/platforms/{platformId}/router": {
7199
+ parameters: {
7200
+ query?: never;
7201
+ header?: never;
7202
+ path?: never;
7203
+ cookie?: never;
7204
+ };
7205
+ get?: never;
7206
+ put?: never;
7207
+ post?: never;
7208
+ delete?: never;
7209
+ options?: never;
7210
+ head?: never;
7211
+ /** Patch router metadata/additionalPrompt only */
7212
+ patch: {
7213
+ parameters: {
7214
+ query?: never;
7215
+ header?: never;
7216
+ path: {
7217
+ platformId: components["parameters"]["PlatformIdPath"];
7218
+ };
7219
+ cookie?: never;
7220
+ };
7221
+ requestBody: {
7222
+ content: {
7223
+ "application/json": components["schemas"]["RouterPatchRequest"];
7224
+ };
7225
+ };
7226
+ responses: {
7227
+ 200: {
7228
+ headers: {
7229
+ [name: string]: unknown;
7230
+ };
7231
+ content: {
7232
+ "application/json": components["schemas"]["PlatformSetupMutationResult"];
7233
+ };
7234
+ };
7235
+ };
7236
+ };
7237
+ trace?: never;
7238
+ };
7239
+ "/api/v2/platforms/{platformId}/router/routing-rules": {
7240
+ parameters: {
7241
+ query?: never;
7242
+ header?: never;
7243
+ path?: never;
7244
+ cookie?: never;
7245
+ };
7246
+ get?: never;
7247
+ put?: never;
7248
+ /** Create one granular routing rule */
7249
+ post: {
7250
+ parameters: {
7251
+ query?: never;
7252
+ header?: never;
7253
+ path: {
7254
+ platformId: components["parameters"]["PlatformIdPath"];
7255
+ };
7256
+ cookie?: never;
7257
+ };
7258
+ requestBody: {
7259
+ content: {
7260
+ "application/json": components["schemas"]["RoutingRuleUpsertRequest"];
7261
+ };
7262
+ };
7263
+ responses: {
7264
+ 201: {
7265
+ headers: {
7266
+ [name: string]: unknown;
7267
+ };
7268
+ content: {
7269
+ "application/json": components["schemas"]["PlatformSetupMutationResult"];
7270
+ };
7271
+ };
7272
+ };
7273
+ };
7274
+ delete?: never;
7275
+ options?: never;
7276
+ head?: never;
7277
+ /** Patch one granular routing rule; no bulk router replace */
7278
+ patch: {
7279
+ parameters: {
7280
+ query?: never;
7281
+ header?: never;
7282
+ path: {
7283
+ platformId: components["parameters"]["PlatformIdPath"];
7284
+ };
7285
+ cookie?: never;
7286
+ };
7287
+ requestBody: {
7288
+ content: {
7289
+ "application/json": components["schemas"]["RoutingRuleUpsertRequest"];
7290
+ };
7291
+ };
7292
+ responses: {
7293
+ 200: {
7294
+ headers: {
7295
+ [name: string]: unknown;
7296
+ };
7297
+ content: {
7298
+ "application/json": components["schemas"]["PlatformSetupMutationResult"];
7299
+ };
7300
+ };
7301
+ };
7302
+ };
7303
+ trace?: never;
7304
+ };
7305
+ "/api/v2/platforms/{platformId}/dialogue-audit/config": {
7306
+ parameters: {
7307
+ query?: never;
7308
+ header?: never;
7309
+ path?: never;
7310
+ cookie?: never;
7311
+ };
7312
+ /**
7313
+ * Reviewer settings of the channel (read-only)
7314
+ * @description `isConfigured=false` means the config row does not exist yet and the returned values are defaults. GET never creates anything. Writing settings is intentionally not exposed to MCP.
7315
+ */
7316
+ get: {
7317
+ parameters: {
7318
+ query?: never;
7319
+ header?: never;
7320
+ path: {
7321
+ platformId: components["parameters"]["PlatformIdPath"];
7322
+ };
7323
+ cookie?: never;
7324
+ };
7325
+ requestBody?: never;
7326
+ responses: {
7327
+ 200: {
7328
+ headers: {
7329
+ [name: string]: unknown;
7330
+ };
7331
+ content: {
7332
+ "application/json": components["schemas"]["DialogueAuditConfig"];
7333
+ };
7334
+ };
7335
+ };
7336
+ };
7337
+ put?: never;
7338
+ post?: never;
7339
+ delete?: never;
7340
+ options?: never;
7341
+ head?: never;
7342
+ patch?: never;
7343
+ trace?: never;
7344
+ };
7345
+ "/api/v2/platforms/{platformId}/dialogue-audit/runs": {
7346
+ parameters: {
7347
+ query?: never;
7348
+ header?: never;
7349
+ path?: never;
7350
+ cookie?: never;
7351
+ };
7352
+ /** Reviewer run history (cursor pagination) */
7353
+ get: {
7354
+ parameters: {
7355
+ query?: {
6727
7356
  cursor?: string;
6728
7357
  limit?: number;
6729
7358
  };
@@ -7702,6 +8331,21 @@ export interface paths {
7702
8331
  sequenceId?: string[];
7703
8332
  /** @description Горизонт сравнительной метрики. Фиксированный набор — иначе окно подбирали бы под ответ */
7704
8333
  horizonMinutes?: 30 | 60 | 90 | 180 | 360 | 720 | 1440;
8334
+ /**
8335
+ * @description Считать ли блок runs. Передайте false, если читаете только шаговые метрики:
8336
+ * расчёт стоит отдельного запроса к БД, а строки таблицы сравнения вариантов и
8337
+ * кастомные отчёты его выбрасывают.
8338
+ */
8339
+ withRuns?: boolean;
8340
+ /**
8341
+ * @description Окно ПРОХОЖДЕНИЯ цепочки для метрики runs: ответил ли человек хоть раз за N дней от входа.
8342
+ *
8343
+ * Не путать с horizonMinutes. Тот живёт на ШАГЕ и обязан вырезать касания, у которых
8344
+ * следующий шаг ушёл раньше конца окна, — на частых цепочках это съедает выборку
8345
+ * (замер 25.08.2026: 56 % при 90 мин). Здесь единица другая — прохождение, — и вырезать
8346
+ * некого: все шаги внутри окна принадлежат этому же прохождению.
8347
+ */
8348
+ runWindowDays?: 1 | 3 | 5 | 7 | 14;
7705
8349
  /**
7706
8350
  * @description Сегмент волны, действовавший на момент отправки шага (последняя волна до касания).
7707
8351
  * У воркспейса без рассылок значений нет — см. `dimensions` в ответе.
@@ -7711,6 +8355,15 @@ export interface paths {
7711
8355
  product?: string[];
7712
8356
  /** @description Транспорт волны (мессенджер). Строгий enum GetCourseTransport */
7713
8357
  channel?: string[];
8358
+ /**
8359
+ * @description Оставить только контакты, которые хоть раз написали сами: у кого за всю переписку
8360
+ * ноль входящих, из отчёта уходят ВСЕ его касания.
8361
+ *
8362
+ * ⚠️ Линза, а не поправка: отбор идёт по исходу, поэтому доли ответов поднимаются во
8363
+ * всех колонках, а шаги перестают быть независимыми — контакт, ответивший на третий
8364
+ * шаг, остаётся в знаменателе первого. Цифры с фильтром и без него несравнимы.
8365
+ */
8366
+ onlyRepliedContacts?: boolean;
7714
8367
  /** @description Момент снимка. Значение в будущем отбрасывается до текущего момента */
7715
8368
  asOf?: string;
7716
8369
  };
@@ -9522,6 +10175,90 @@ export interface paths {
9522
10175
  patch?: never;
9523
10176
  trace?: never;
9524
10177
  };
10178
+ "/api/v2/workspaces/{workspaceId}/link-tracking-domain": {
10179
+ parameters: {
10180
+ query?: never;
10181
+ header?: never;
10182
+ path?: never;
10183
+ cookie?: never;
10184
+ };
10185
+ /**
10186
+ * Домен коротких ссылок воркспейса
10187
+ * @description Хост, с которого уходят короткие ссылки этого воркспейса, и зоны, доступные для назначения. ⚠️ Чтение под `mcp:platform-setup`, а не под правом аналитики: ответ содержит список зон ПЛАТФОРМЫ, а не цифры воркспейса.
10188
+ */
10189
+ get: {
10190
+ parameters: {
10191
+ query?: never;
10192
+ header?: never;
10193
+ path: {
10194
+ workspaceId: components["parameters"]["BroadcastWorkspaceId"];
10195
+ };
10196
+ cookie?: never;
10197
+ };
10198
+ requestBody?: never;
10199
+ responses: {
10200
+ /** @description OK */
10201
+ 200: {
10202
+ headers: {
10203
+ [name: string]: unknown;
10204
+ };
10205
+ content: {
10206
+ "application/json": components["schemas"]["WorkspaceLinkDomain"];
10207
+ };
10208
+ };
10209
+ };
10210
+ };
10211
+ /**
10212
+ * Назначить или сбросить домен коротких ссылок
10213
+ * @description `domain: null` возвращает воркспейс на общий домен платформы. ⚠️ Прежний хост остаётся закреплённым за воркспейсом НАВСЕГДА: короткий адрес собирается в момент отправки и вшит в уже разосланные сообщения, поэтому отдать имя другому клиенту нельзя — 409. Смена влияет только на НОВЫЕ ссылки; уже отправленные продолжают открываться на прежнем адресе.
10214
+ */
10215
+ put: {
10216
+ parameters: {
10217
+ query?: never;
10218
+ header?: never;
10219
+ path: {
10220
+ workspaceId: components["parameters"]["BroadcastWorkspaceId"];
10221
+ };
10222
+ cookie?: never;
10223
+ };
10224
+ requestBody: {
10225
+ content: {
10226
+ "application/json": components["schemas"]["UpdateWorkspaceLinkDomainRequest"];
10227
+ };
10228
+ };
10229
+ responses: {
10230
+ /** @description OK */
10231
+ 200: {
10232
+ headers: {
10233
+ [name: string]: unknown;
10234
+ };
10235
+ content: {
10236
+ "application/json": components["schemas"]["WorkspaceLinkDomain"];
10237
+ };
10238
+ };
10239
+ /** @description Домен не проходит правила платформы (зона, формат имени, занятое имя) */
10240
+ 400: {
10241
+ headers: {
10242
+ [name: string]: unknown;
10243
+ };
10244
+ content?: never;
10245
+ };
10246
+ /** @description Хост занят другим воркспейсом, в том числе выведенным из обращения */
10247
+ 409: {
10248
+ headers: {
10249
+ [name: string]: unknown;
10250
+ };
10251
+ content?: never;
10252
+ };
10253
+ };
10254
+ };
10255
+ post?: never;
10256
+ delete?: never;
10257
+ options?: never;
10258
+ head?: never;
10259
+ patch?: never;
10260
+ trace?: never;
10261
+ };
9525
10262
  "/api/v2/workspaces/{workspaceId}/broadcast-analytics": {
9526
10263
  parameters: {
9527
10264
  query?: never;
@@ -10009,6 +10746,8 @@ export interface paths {
10009
10746
  sortBy?: components["parameters"]["BroadcastRecipientSortBy"];
10010
10747
  /** @description Направление серверной сортировки списка получателей. */
10011
10748
  sortOrder?: components["parameters"]["BroadcastRecipientSortOrder"];
10749
+ /** @description Сузить выборку одной отслеживаемой ссылкой. Уточнение оператора внутри окна: применяется и к списку, и к счётчику — «показано N из M» обязано сходиться. */
10750
+ linkId?: string;
10012
10751
  metric: "sent" | "delivered" | "entered" | "deepDialog" | "linkIssued" | "clicked" | "handedOff" | "notDelivered" | "notSent";
10013
10752
  reason?: "NO_MESSENGER" | "ACTIVE_INVOICE_SAME_PRODUCT" | "ACTIVE_DEAL_SAME_PRODUCT" | "PAID_SAME_PRODUCT" | "ACTIVE_DEAL_OTHER_PRODUCT" | "MANAGER_ASSIGNED_ACTIVE_DEAL" | "PRODUCT_CONTEXT_MISSING" | "GETCOURSE_CHECK_ERROR" | "ALREADY_SENT" | "USER_NOT_FOUND";
10014
10753
  };
@@ -10238,6 +10977,10 @@ export interface paths {
10238
10977
  channel?: components["parameters"]["BroadcastChannel"];
10239
10978
  /** @description ID конкретной волны. */
10240
10979
  importJobId?: components["parameters"]["BroadcastImportJobId"];
10980
+ /** @description Колонка сортировки косвенных оплат — те же, что у вкладки «Оплаты», минус `confidence`/`matchReason`: атрибуции по сделке у кандидата нет, её признал оператор. */
10981
+ sortBy?: components["parameters"]["BroadcastIndirectSortBy"];
10982
+ /** @description Направление серверной сортировки списка сделок и оплат. */
10983
+ sortOrder?: components["parameters"]["BroadcastDealSortOrder"];
10241
10984
  page?: components["parameters"]["BroadcastPage"];
10242
10985
  pageSize?: components["parameters"]["BroadcastPageSize"];
10243
10986
  };
@@ -10646,7 +11389,9 @@ export interface paths {
10646
11389
  /** @description Мессенджеры волны (транспорты GetCourse + UNKNOWN — канал не определён), мультивыбор. Деньги фильтруются по скалярному каналу сделки. */
10647
11390
  channels?: components["parameters"]["BroadcastChannels"];
10648
11391
  /** @description Сегмент очереди. `resolved` = `confirmed` + `rejected` одним списком; UI пользуется раздельными сегментами, выгрузке чаще нужен общий. */
10649
- view?: "decidable" | "external_mailing" | "excluded" | "confirmed" | "rejected" | "resolved";
11392
+ view?: "decidable" | "external_mailing" | "excluded" | "confirmed" | "rejected" | "resolved" | "potential";
11393
+ /** @description Режим атрибуции для сегмента `potential`: `cohort` датирует по волне, `period` — по оплате. Отдельное имя потому, что `view` занят сегмент-переключателем; остальные сегменты параметр игнорируют. */
11394
+ attributionView?: "cohort" | "period";
10650
11395
  status?: components["schemas"]["PaymentCandidateStatus"];
10651
11396
  eligibility?: components["schemas"]["PaymentCandidateEligibility"];
10652
11397
  /** @description Кем принято решение: `human` — пользователь в вебе или оператор в Telegram, `script` — служебный прогон сверки. Сужает выбранное `view`, а не заменяет его. */
@@ -18315,8 +19060,7 @@ export interface components {
18315
19060
  contactId: string;
18316
19061
  /** @description Registration deal id для свежего пина Шага 1 */
18317
19062
  dealId?: string;
18318
- /** @enum {string} */
18319
- transport?: "VK" | "Telegram" | "MAX" | "SMS" | "Email" | "Site";
19063
+ transport?: components["schemas"]["GetCourseTransport"];
18320
19064
  dialogId?: string;
18321
19065
  /** Format: email */
18322
19066
  email?: string;
@@ -18358,7 +19102,7 @@ export interface components {
18358
19102
  * @enum {string}
18359
19103
  */
18360
19104
  launchType: "status";
18361
- channels: ("VK" | "Telegram" | "MAX" | "SMS" | "Email" | "Site")[];
19105
+ channels: components["schemas"]["GetCourseTransport"][];
18362
19106
  funnel?: string;
18363
19107
  segment?: string;
18364
19108
  /** @description Явное бизнес-правило отбора; требует segment. */
@@ -18414,6 +19158,263 @@ export interface components {
18414
19158
  dryRunHash: string;
18415
19159
  state?: components["schemas"]["GetCourseWaveRunState"];
18416
19160
  };
19161
+ GetCourseColdWelcomeContact: {
19162
+ /** @description getcourse_user_id контакта. */
19163
+ contactId: string;
19164
+ /** @description Пин заказа для штампа полей сделки. */
19165
+ dealId?: string;
19166
+ /**
19167
+ * Format: date-time
19168
+ * @description Точный момент входа контакта в когорту (ISO 8601, зона ОБЯЗАТЕЛЬНА — …Z либо ±ЧЧ:ММ). На нём считается свежесть в «Аналитике рассылок»: возраст = время отправки минус segmentEnteredAt. Заполняется, когда предсписок собран ПРАВИЛОМ и у каждой строки есть свой момент события (например eventAt регистрации). Не передан — возраст строки остаётся неизвестным. Дату запуска сюда подставлять нельзя: она схлопнула бы месяцы когорт в одну корзину.
19169
+ */
19170
+ segmentEnteredAt?: string;
19171
+ };
19172
+ /** @description Ровно одна аудитория — createdAfter ЛИБО contacts. */
19173
+ GetCourseColdWelcomePreviewRequest: {
19174
+ /** Format: uuid */
19175
+ platformId: string;
19176
+ /**
19177
+ * Format: uuid
19178
+ * @description Источник каналов и «Платформы по умолчанию».
19179
+ */
19180
+ mailingVariantId?: string;
19181
+ /**
19182
+ * Format: date-time
19183
+ * @description Аудитория «по дате» — нижняя граница даты создания контакта.
19184
+ */
19185
+ createdAfter?: string;
19186
+ contacts?: components["schemas"]["GetCourseColdWelcomeContact"][];
19187
+ channels?: components["schemas"]["GetCourseTransport"][];
19188
+ /** @deprecated */
19189
+ channelsMode?: components["schemas"]["ColdWelcomeChannelsMode"];
19190
+ };
19191
+ /**
19192
+ * @deprecated
19193
+ * @description ⚠️ УСТАРЕЛО и на поведение НЕ влияет (с 23.08.2026). Режим применялся ко ВСЕМУ списку сразу, из-за чего отметка Email годами оставалась молчаливым no-op. Теперь список channels значит «слать сюда», а судьбу каждого канала решает сервер: мессенджер (Telegram/VK/MAX) уходит, только если школа подтвердила его наличие у контакта; SMS — только при известном телефоне; Email, WhatsApp, Viber, Сайт, Chatium уходят вслепую. Поле принимается ради обратной совместимости и игнорируется.
19194
+ * @enum {string}
19195
+ */
19196
+ ColdWelcomeChannelsMode: "RESTRICT" | "ADD";
19197
+ GetCourseColdWelcomePreviewResponse: {
19198
+ /** @description Выбранные каналы, которых НЕТ в allowlist площадки: они не уедут ни в каком режиме. Чинится галочкой в настройках площадки, поэтому возвращаются ИМЕНАМИ, а не числом. */
19199
+ channelsNotAllowedByPlatform?: components["schemas"]["GetCourseTransport"][];
19200
+ /** @description Сколько ещё МОЖЕТ получить первое сообщение. */
19201
+ totalContacts: number;
19202
+ /** @description Уже получали — приветствие одноразово НА КОНТАКТ, а не на рассылку. */
19203
+ alreadyWelcomed: number;
19204
+ /** @description Всего найдено под границей. */
19205
+ foundContacts: number;
19206
+ };
19207
+ /** @description Не больше ОДНОЙ аудитории: contacts (поимённый список) ЛИБО currentAnchorValue (когорта). Без обеих — вся площадка (все контакты с непустым якорем). */
19208
+ GetCourseAnchorRefreshRequest: {
19209
+ /**
19210
+ * Format: uuid
19211
+ * @description Обязателен: набор перечитываемых якорей площадочный — якоря включённых календарных цепочек, пересечённые с картой полей сделки.
19212
+ */
19213
+ platformId: string;
19214
+ /** @description Когортным предикатом НЕ фильтруется — оператор назвал этих людей поимённо. */
19215
+ contacts?: components["schemas"]["GetCourseColdWelcomeContact"][];
19216
+ /** @description Только контакты, чей якорь СЕЙЧАС равен этой дате — случай «эфир 19.08 перенесли». Сравнение по КАЛЕНДАРНОМУ ДНЮ: «19.08.2026» и «2026-08-19» — одна дата. Неразбираемое значение отвергается 400, а не даёт пустой прогон. */
19217
+ currentAnchorValue?: string;
19218
+ };
19219
+ GetCourseAnchorRefreshPreviewResponse: {
19220
+ /** @description Якоря включённых календарных цепочек площадки. */
19221
+ anchorVariables: string[];
19222
+ /** @description Из них замаплены на поля сделки — только эти прогон и перечитает. Пустой список означает «перечитывать нечем». */
19223
+ refreshableVariables: string[];
19224
+ contactsMatched: number;
19225
+ /** @description Им прогон откажет (SKIPPED_NO_PINNED_DEAL). */
19226
+ withoutPinnedDeal: number;
19227
+ /** @description Строк присланного списка, которым не нашлось контакта в базе площадки (только файловая аудитория). «Прислали 500, найдено 200» — сначала импорт контактов. */
19228
+ notInBase: number;
19229
+ /** @description Переменная → текущее значение → сколько контактов его несут. */
19230
+ currentValues: {
19231
+ [key: string]: {
19232
+ [key: string]: number;
19233
+ };
19234
+ };
19235
+ };
19236
+ GetCourseAnchorRefreshStartResponse: {
19237
+ /** @description Отдаётся ВСЕГДА, включая отказные ветки: по нему ищутся итоги в логах и строки audit_logs этого прогона. */
19238
+ correlationId: string;
19239
+ started: boolean;
19240
+ /** @description По этой площадке прогон уже идёт — второй не запускается. */
19241
+ alreadyRunning: boolean;
19242
+ refreshableVariables: string[];
19243
+ };
19244
+ /** @description Ровно один источник текста (message ЛИБО mailingVariantId) и ровно одна аудитория (createdAfter ЛИБО contacts). */
19245
+ GetCourseColdWelcomeLaunchRequest: {
19246
+ /**
19247
+ * Format: uuid
19248
+ * @description Можно опустить, если у рассылки задана «Платформа по умолчанию».
19249
+ */
19250
+ platformId?: string;
19251
+ /** Format: date-time */
19252
+ createdAfter?: string;
19253
+ contacts?: components["schemas"]["GetCourseColdWelcomeContact"][];
19254
+ /** @description Разовый текст запуска. */
19255
+ message?: string;
19256
+ /**
19257
+ * Format: uuid
19258
+ * @description Сохранённая рассылка — текст и метки берутся из неё.
19259
+ */
19260
+ mailingVariantId?: string;
19261
+ /** @description Ключ — числовой fieldId GetCourse. Штампуются ПОСЛЕ успешной отправки. Пустой объект НЕ равен отсутствию ключа: он означает «на этом запуске без полей» и гасит дефолты. */
19262
+ dealFields?: {
19263
+ [key: string]: string | number | boolean | null;
19264
+ };
19265
+ /** @description Метка сегмента. Аудиторию НЕ отбирает. Если у рассылки есть текст именно для этого сегмента, он выбирает текст запуска — и тогда аудитория обязана быть файловой. */
19266
+ segment?: string;
19267
+ productCode?: string;
19268
+ funnel?: string;
19269
+ /** @description Человекочитаемое имя ЭТОГО запуска — подпись когорты в «Аналитике рассылок». Не имя рассылки и не метка сегмента: те одинаковы у всех запусков, а разрез «по запускам» строится именно по подписи. Пусто — подпись собирается из даты запуска, имени рассылки и меток, так что запуски всё равно остаются различимыми. */
19270
+ cohortLabel?: string;
19271
+ channels?: components["schemas"]["GetCourseTransport"][];
19272
+ /** @deprecated */
19273
+ channelsMode?: components["schemas"]["ColdWelcomeChannelsMode"];
19274
+ };
19275
+ GetCourseColdWelcomeLaunchResponse: {
19276
+ /** Format: uuid */
19277
+ jobId: string;
19278
+ totalContacts: number;
19279
+ };
19280
+ GetCourseColdWelcomeBatchSegment: {
19281
+ /** @description Он же выбирает текст, если у рассылки есть посегментные тексты. */
19282
+ segment?: string;
19283
+ productCode?: string;
19284
+ funnel?: string;
19285
+ /** @description Подпись запуска ЭТОГО блока. У пакета каждый сегмент — отдельный запуск со своей задачей и когортой, поэтому подпись задаётся посегментно; общая на пакет схлопнула бы их в отчёте в одну корзину. */
19286
+ cohortLabel?: string;
19287
+ dealFields?: {
19288
+ [key: string]: string | number | boolean | null;
19289
+ };
19290
+ contacts: components["schemas"]["GetCourseColdWelcomeContact"][];
19291
+ };
19292
+ /** @description Ровно один источник текста — message ЛИБО mailingVariantId. */
19293
+ GetCourseColdWelcomeBatchRequest: {
19294
+ /** Format: uuid */
19295
+ platformId?: string;
19296
+ message?: string;
19297
+ /** Format: uuid */
19298
+ mailingVariantId?: string;
19299
+ segments: components["schemas"]["GetCourseColdWelcomeBatchSegment"][];
19300
+ /** @description Политика на ВЕСЬ пакет, снимок на старте. Ключ не передан — дефолт рассылки; пустой массив — без политики. */
19301
+ channels?: components["schemas"]["GetCourseTransport"][];
19302
+ /** @deprecated */
19303
+ channelsMode?: components["schemas"]["ColdWelcomeChannelsMode"];
19304
+ };
19305
+ GetCourseColdWelcomeBatchResponse: {
19306
+ /** Format: uuid */
19307
+ batchId: string;
19308
+ /** @description Сколько сегментов поставлено в очередь */
19309
+ segments: number;
19310
+ };
19311
+ GetCourseColdWelcomeBatchSegmentStatus: {
19312
+ position: number;
19313
+ segment: string | null;
19314
+ /** @enum {string} */
19315
+ status: "PENDING" | "RUNNING" | "COMPLETED" | "FAILED" | "CANCELLED";
19316
+ contactsCount: number;
19317
+ /** Format: uuid */
19318
+ importJobId: string | null;
19319
+ error: string | null;
19320
+ /** @description Каналы, подтверждённые на старте пакета. Пусто — ограничения нет. */
19321
+ coldWelcomeChannels: components["schemas"]["GetCourseTransport"][];
19322
+ /** @description true — каналы заданы явно на запуске; false — унаследованы от рассылки. */
19323
+ coldWelcomeChannelsExplicit: boolean;
19324
+ };
19325
+ GetCourseColdWelcomeBatchStatus: {
19326
+ /** Format: uuid */
19327
+ batchId: string;
19328
+ /** @enum {string} */
19329
+ state: "RUNNING" | "COMPLETED" | "FAILED" | "CANCELLED";
19330
+ segments: components["schemas"]["GetCourseColdWelcomeBatchSegmentStatus"][];
19331
+ /** @description Драйвер пакета доказуемо оборвался (протух пульс) — остаток поднимается через resume. Судить по статусу задачи нельзя: она живёт в том же процессе и замерзает вместе с ним. */
19332
+ stalled: boolean;
19333
+ };
19334
+ /** @description Ключи — имена колонок экспорта GetCourse (snake_case), а не поля API: их читает тот же разбор, что и файловый импорт. Пустая строка считается отсутствующим значением. */
19335
+ GetCourseContactImportRow: {
19336
+ /** @description getcourse_user_id */
19337
+ contact_id: string;
19338
+ /** @description Пин заказа */
19339
+ deal_id?: string;
19340
+ /** @description resp_id */
19341
+ dialog_id?: string;
19342
+ transport?: string;
19343
+ /** Format: email */
19344
+ email?: string;
19345
+ phone?: string;
19346
+ /** @description Влияет на текст: обращение подставляется системным {greeting}, и у контакта без имени обращения не будет вовсе (а не голая запятая). */
19347
+ first_name?: string;
19348
+ last_name?: string;
19349
+ };
19350
+ GetCourseContactsImportRequest: {
19351
+ /** Format: uuid */
19352
+ platformId: string;
19353
+ contacts: components["schemas"]["GetCourseContactImportRow"][];
19354
+ /**
19355
+ * @description Отсеивать контакты без Telegram/MAX/VK. Проверка — API-вызов на КАЖДЫЙ контакт, поэтому на больших списках импорт идёт заметно дольше.
19356
+ * @default true
19357
+ */
19358
+ checkMessengerPresence: boolean;
19359
+ };
19360
+ /** @description При наличии валидных строк возвращается jobId и totalRows; если валидных не оказалось вовсе — validationErrors и errorCount, задача при этом НЕ создаётся. */
19361
+ GetCourseContactsImportResponse: {
19362
+ /** Format: uuid */
19363
+ jobId?: string;
19364
+ totalRows?: number;
19365
+ validationErrors?: string[];
19366
+ errorCount?: number;
19367
+ message: string;
19368
+ };
19369
+ BroadcastLaunch: {
19370
+ id: string;
19371
+ /** @description Наша отправка либо волна по файлу */
19372
+ kind: string;
19373
+ status: string;
19374
+ channel: string;
19375
+ /** Format: uuid */
19376
+ platformId?: string | null;
19377
+ /** Format: uuid */
19378
+ mailingVariantId?: string | null;
19379
+ mailingVariantName?: string | null;
19380
+ /** @description Снимок текста на момент запуска — правка рассылки его не меняет. */
19381
+ messageSnapshot?: string | null;
19382
+ segment?: string | null;
19383
+ productCode?: string | null;
19384
+ funnel?: string | null;
19385
+ totalContacts: number;
19386
+ sentCount: number;
19387
+ failedCount: number;
19388
+ /** @description Счётчик по каждому исходу отправки. */
19389
+ outcomes?: {
19390
+ [key: string]: number;
19391
+ } | null;
19392
+ /** @description Сколько отправок ушло ВСЛЕПУЮ: канал взят резервным транспортом площадки, а не доказан привязками контакта или его ответом. Это ПОДМНОЖЕСТВО sentCount, а не отдельный исход — сообщение ушло. Без него «доставлено в мессенджер» и «упало в личный кабинет сайта» в истории неразличимы. null — у волн (отправляет процесс школы) и у запусков до появления счётчика; это НЕ то же, что 0. */
19393
+ sentWithoutChannelEvidence?: number | null;
19394
+ /** Format: date-time */
19395
+ createdAt: string;
19396
+ /** Format: date-time */
19397
+ completedAt?: string | null;
19398
+ };
19399
+ BroadcastLaunchesPage: {
19400
+ items: components["schemas"]["BroadcastLaunch"][];
19401
+ hasMore: boolean;
19402
+ };
19403
+ BroadcastVariantSummary: {
19404
+ /** Format: uuid */
19405
+ mailingVariantId: string;
19406
+ launches: number;
19407
+ sentTotal: number;
19408
+ /** Format: date-time */
19409
+ lastLaunchAt?: string | null;
19410
+ };
19411
+ BroadcastLabelSuggestions: {
19412
+ segments: string[];
19413
+ productCodes: string[];
19414
+ funnels: string[];
19415
+ };
19416
+ /** @enum {string} */
19417
+ GetCourseTransport: "Site" | "Email" | "SMS" | "Telegram" | "Facebook" | "VK" | "Chatium" | "WhatsApp" | "Viber" | "MAX";
18417
19418
  GetCourseWaveRunCounters: {
18418
19419
  PENDING: number;
18419
19420
  CLAIMED: number;
@@ -18451,7 +19452,7 @@ export interface components {
18451
19452
  position: number;
18452
19453
  getcourseUserId: number;
18453
19454
  dealId: number | null;
18454
- transport: ("VK" | "Telegram" | "MAX" | "SMS" | "Email" | "Site") | null;
19455
+ transport: components["schemas"]["GetCourseTransport"] | null;
18455
19456
  dialogId: string | null;
18456
19457
  leadLastActiveAt: string | null;
18457
19458
  segmentEnteredAt: string | null;
@@ -18469,7 +19470,7 @@ export interface components {
18469
19470
  * @enum {string}
18470
19471
  */
18471
19472
  launchType: "status";
18472
- channels: ("VK" | "Telegram" | "MAX" | "SMS" | "Email" | "Site")[];
19473
+ channels: components["schemas"]["GetCourseTransport"][];
18473
19474
  funnel?: string;
18474
19475
  segment?: string;
18475
19476
  /** @description Явное бизнес-правило отбора; требует segment. */
@@ -18813,9 +19814,21 @@ export interface components {
18813
19814
  metadata?: {
18814
19815
  [key: string]: unknown;
18815
19816
  };
18816
- actions?: {
19817
+ /** @description Набор действий триггера. Конфиг действия кладётся в ОТДЕЛЬНОЕ поле, имя которого зависит от actionType: правило camelCase(actionType)+"Config" (CRM_UPDATE_FIELD → crmUpdateFieldConfig). Пять легаси-исключений: CRM_MOVE_STAGE → crmConfig, SCHEDULE_FOLLOWUP → scheduleFollowUpConfig, SUMMARIZE_DIALOG → summarizeConfig, SEND_TELEGRAM_CHANNEL_MESSAGE → telegramChannelConfig, CRM_RENAME_DEAL → renameDealConfig. В ОТВЕТЕ (GET триггеров, platform-context) тот же конфиг приходит под именем СВЯЗИ Prisma (crmMoveStage, scheduleFollowUp, summarizeAction, telegramChannelMessage, renameDeal) — пересылая прочитанное на запись, его надо переименовать в ключ входа, иначе whitelist+forbidNonWhitelisted ответит «property … should not exist». Действие с ОБЯЗАТЕЛЬНЫМ конфигом, присланное без него, отвергается 400 (раньше оно сохранялось пустым и отказывало только в рантайме). Канон имён и обязательности — ai-aniomaly/src/core/application/tools/constants/trigger-action-config.constants.ts. */
19818
+ actions?: ({
19819
+ /** @description Prisma ActionType */
19820
+ actionType: string;
19821
+ priority?: number;
19822
+ isEnabled?: boolean;
19823
+ /** @description Следующие действия выполнятся даже при падении этого */
19824
+ continueOnError?: boolean;
19825
+ /** @description Конфиг CRM_MOVE_STAGE: crmId, crmType (AMOCRM|BITRIX24|GETCOURSE), statusId, pipelineId + pipelineCrmId (рекомендуются), note. В ответе — crmMoveStage. */
19826
+ crmConfig?: {
19827
+ [key: string]: unknown;
19828
+ };
19829
+ } & {
18817
19830
  [key: string]: unknown;
18818
- }[];
19831
+ })[];
18819
19832
  /** @description true → replace the full action set (delete-and-recreate, like UI). Without it, actions on an existing trigger are rejected. */
18820
19833
  replaceActions?: boolean;
18821
19834
  };
@@ -18878,7 +19891,7 @@ export interface components {
18878
19891
  /** @description Ненулевое значение означает, что пункт не будет отправлен. */
18879
19892
  blockedReason: string | null;
18880
19893
  /** @description null означает выбор транспорта по каноническому каналу контакта. */
18881
- getcourseTransports: ("VK" | "Telegram" | "MAX" | "SMS" | "Email" | "Site")[] | null;
19894
+ getcourseTransports: components["schemas"]["GetCourseTransport"][] | null;
18882
19895
  skippedEffects: ("crm_stage" | "crm_note" | "webhook" | "platform_log" | "attachments")[];
18883
19896
  attachmentCount: number;
18884
19897
  };
@@ -18987,6 +20000,33 @@ export interface components {
18987
20000
  /** @description Медиана длительности ЗАКРЫТЫХ окон, минуты */
18988
20001
  medianWindowMinutes: number | null;
18989
20002
  };
20003
+ FollowUpRunReply: {
20004
+ /**
20005
+ * Format: uuid
20006
+ * @description null — итог по разрезу
20007
+ */
20008
+ sequenceId: string | null;
20009
+ /** @description Прохождений, начавшихся в периоде и уже созревших */
20010
+ started: number;
20011
+ /** @description Из них ответивших хотя бы раз за окно */
20012
+ replied: number;
20013
+ /**
20014
+ * @description Начавшихся, но окно ещё не вышло. Отдельным числом, а не нулём в числителе: ответ ещё
20015
+ * может прийти, и ноль занижал бы долю тем сильнее, чем свежее период.
20016
+ */
20017
+ immature: number;
20018
+ };
20019
+ /**
20020
+ * @description Отклик на ПРОХОЖДЕНИЕ цепочки — метрика уровня цепочки, независимая от horizonMinutes.
20021
+ *
20022
+ * Отвечает на вопрос «работает ли цепочка», а НЕ «какой шаг сработал»: атрибутировать ответ
20023
+ * конкретному шагу она не пытается, поэтому и вырезать никого не должна.
20024
+ */
20025
+ FollowUpRunsSummary: {
20026
+ windowDays: number;
20027
+ total: components["schemas"]["FollowUpRunReply"];
20028
+ bySequence: components["schemas"]["FollowUpRunReply"][];
20029
+ };
18990
20030
  FollowUpReactionsResponse: {
18991
20031
  byStep: (components["schemas"]["FollowUpReactionMetrics"] & {
18992
20032
  /** Format: uuid */
@@ -19042,7 +20082,19 @@ export interface components {
19042
20082
  * @description Момент снимка; передайте его в drill-down как asOf
19043
20083
  */
19044
20084
  calculatedAt: string;
20085
+ /**
20086
+ * @description Окно, ПО КОТОРОМУ посчитаны сравнительные цифры. Подбирается сервером автоматически —
20087
+ * самый длинный кандидат, у которого отсев цензурированием в пределах порога.
20088
+ * Явно переданный horizonMinutes уважается как экспертный обход.
20089
+ */
19045
20090
  horizonMinutes: number;
20091
+ /**
20092
+ * @description picked — окно подобрано (или задано клиентом); no-reliable-horizon — ни один кандидат
20093
+ * не прошёл порог, сравнивать нельзя; no-data — сравнивать нечего.
20094
+ * @enum {string}
20095
+ */
20096
+ horizonReason: "picked" | "no-reliable-horizon" | "no-data";
20097
+ runs: components["schemas"]["FollowUpRunsSummary"];
19046
20098
  /** @description Потолок операционного окна */
19047
20099
  maxWindowMinutes: number;
19048
20100
  /** Format: date-time */
@@ -22191,6 +23243,50 @@ export interface components {
22191
23243
  defaultChannels?: string[];
22192
23244
  defaultDealFields?: Record<string, never> | null;
22193
23245
  };
23246
+ WorkspaceLinkDomain: {
23247
+ /**
23248
+ * @description Хост без схемы (`ksamata.besales.pro`); null — используется общий домен платформы.
23249
+ * @example ksamata.besales.pro
23250
+ */
23251
+ domain: string | null;
23252
+ /**
23253
+ * @description Зоны, доступные для назначения. Пусто — выбор домена на платформе не настроен (зона без wildcard-сертификата отдала бы человеку ошибку сертификата).
23254
+ * @example [
23255
+ * "besales.pro"
23256
+ * ]
23257
+ */
23258
+ zones: string[];
23259
+ /**
23260
+ * @description Адрес, который используется, пока свой домен не задан.
23261
+ * @example https://go-ru.besales.ai
23262
+ */
23263
+ defaultBaseUrl: string | null;
23264
+ /** @description Места в конфигурации воркспейса, где остался короткий адрес на ЧУЖОМ хосте. ⚠️ Возникают потому, что `staticUrl` вставляется в тексты СНИМКОМ, и переезд домена его не переписывает: такие места надо перевставить вручную. Пустой массив — всё указывает на текущий хост. */
23265
+ staleUsages: {
23266
+ /**
23267
+ * @description Что это за место — чтобы оператор понял, где искать.
23268
+ * @enum {string}
23269
+ */
23270
+ place: "AGENT_FACTS" | "AGENT_PROMPT" | "AGENT_GREETING" | "AGENT_SCRIPT" | "FOLLOW_UP" | "BROADCAST_VARIANT" | "QA" | "WORKSPACE_VARIABLE";
23271
+ /**
23272
+ * @description Имя сущности (агента, цепочки, варианта рассылки).
23273
+ * @example Светлана · вебинарная воронка
23274
+ */
23275
+ name: string;
23276
+ /**
23277
+ * @description Хост, который там остался.
23278
+ * @example go.besales.ai
23279
+ */
23280
+ host: string;
23281
+ }[];
23282
+ };
23283
+ UpdateWorkspaceLinkDomainRequest: {
23284
+ /**
23285
+ * @description Хост без схемы, ровно один уровень под разрешённой зоной; null — вернуться на общий домен платформы. Поле обязательное И nullable одновременно: пустое тело `{}` обязано быть ошибкой, а не молчаливым сбросом.
23286
+ * @example ksamata.besales.pro
23287
+ */
23288
+ domain: string | null;
23289
+ };
22194
23290
  TrackedLink: {
22195
23291
  /** Format: uuid */
22196
23292
  id: string;
@@ -22198,7 +23294,7 @@ export interface components {
22198
23294
  /** @description Часть плейсхолдера; неизменяема после создания. */
22199
23295
  slug: string;
22200
23296
  targetUrl: string;
22201
- /** @description Анонимный короткий адрес для ручной вставки. null — трекинг не сконфигурирован (LINK_TRACKING_BASE_URL не задан). */
23297
+ /** @description Анонимный короткий адрес для ручной вставки. Домен берётся из настройки воркспейса, а при её отсутствии — из LINK_TRACKING_BASE_URL; null означает, что выдавать ссылки некуда. Уже сохранённый где-либо адрес НЕ переписывается при смене домена: он продолжает работать, но содержит прежнее имя. */
22202
23298
  staticUrl: string | null;
22203
23299
  /** @description Готовый токен для текста исходящего, например {{link:webinar-gkt}}. Собирается сервером — вторая сборка на клиенте разошлась бы с разбором. */
22204
23300
  placeholder: string;
@@ -22406,8 +23502,12 @@ export interface components {
22406
23502
  segment: string | null;
22407
23503
  product: string | null;
22408
23504
  reason: string | null;
23505
+ /** @description Ссылки, ушедшие получателю в окне его волны, со временем перехода. Массив, а не поле: у волны бывает несколько ссылок. */
23506
+ links: components["schemas"]["BroadcastRecipientLink"][];
22409
23507
  };
22410
23508
  BroadcastDealItem: {
23509
+ /** Format: uuid */
23510
+ id: string;
22411
23511
  dealId: number;
22412
23512
  dealNumber: string | null;
22413
23513
  /** Format: uuid */
@@ -22446,11 +23546,30 @@ export interface components {
22446
23546
  actionType: string;
22447
23547
  count: number;
22448
23548
  };
23549
+ BroadcastRecipientLink: {
23550
+ /** @description Идентификатор выдачи — одна ссылка бывает выдана дважды */
23551
+ issueId: string;
23552
+ linkId: string;
23553
+ name: string;
23554
+ /** @description Адрес НА МОМЕНТ ВЫДАЧИ; правка каталога историю не переписывает */
23555
+ targetUrl: string;
23556
+ /** @description Первый живой переход (МСК); null — не нажимали */
23557
+ clickedAt: string | null;
23558
+ /** @description Сколько раз по ЭТОЙ выдаче перешли (боты отсеяны). Не выводится из clickedAt: там MIN, и два перехода по одной выдаче неотличимы от одного. 0 — не нажимали */
23559
+ clickCount: number;
23560
+ };
23561
+ BroadcastLinkOption: {
23562
+ linkId: string;
23563
+ name: string;
23564
+ recipients: number;
23565
+ };
22449
23566
  BroadcastRecipientsDrilldownResponse: {
22450
23567
  items: components["schemas"]["BroadcastRecipientItem"][];
22451
23568
  total: number;
22452
23569
  page: number;
22453
23570
  pageSize: number;
23571
+ /** @description Ссылки ВСЕЙ выборки — справочник фильтра. Считается без самого фильтра и без пагинации: иначе после выбора вернуться к «любой ссылке» будет нечем. */
23572
+ linkOptions: components["schemas"]["BroadcastLinkOption"][];
22454
23573
  };
22455
23574
  BroadcastDealsDrilldownResponse: {
22456
23575
  items: components["schemas"]["BroadcastDealItem"][];
@@ -22489,6 +23608,8 @@ export interface components {
22489
23608
  confirmedBy: string | null;
22490
23609
  /** Format: date-time */
22491
23610
  confirmedAt: string | null;
23611
+ name: string | null;
23612
+ product: string | null;
22492
23613
  };
22493
23614
  BroadcastIndirectPaymentsResponse: {
22494
23615
  items: components["schemas"]["BroadcastIndirectPaymentItem"][];
@@ -24436,7 +25557,11 @@ export interface components {
24436
25557
  BroadcastDealSortBy: "paidAt" | "client" | "amount" | "channels" | "segment" | "funnel" | "product" | "confidence" | "matchReason";
24437
25558
  /** @description Направление серверной сортировки списка сделок и оплат. */
24438
25559
  BroadcastDealSortOrder: "asc" | "desc";
25560
+ /** @description Колонка сортировки косвенных оплат — те же, что у вкладки «Оплаты», минус `confidence`/`matchReason`: атрибуции по сделке у кандидата нет, её признал оператор. */
25561
+ BroadcastIndirectSortBy: "paidAt" | "client" | "amount" | "channels" | "segment" | "funnel" | "product";
24439
25562
  WorkspaceIdPath: string;
25563
+ ColdWelcomeBatchIdPath: string;
25564
+ ColdWelcomeJobIdPath: string;
24440
25565
  GetCourseWaveRunBatchIdPath: string;
24441
25566
  /** @description workspaceId */
24442
25567
  VoiceTenantHeader: string;