Skip to content

Протоколы встреч

Семейство protocols.

norm_protocol_types

Типы встреч компании и подсказки к ним — весь справочник одним ответом, спрашивайте один раз за прогон. Тип распознавайте по aliases детерминированно: совпало написание в названии встречи — передавайте type_id и unit_id типа в запись и применяйте его подсказку. Не совпало — type_id не передавайте, подразделение определяйте по участникам, а подсказку берите у типа из fallback_type_id, если он указан. Режим replace — самостоятельная инструкция, не вкладывайте её в свой каркас. truncated: true у типа — подсказка обрезана ради предела размера ответа, НЕ применяйте её: отрезан конец, где обычно и лежат требования. Пустой массив — у компании нет типов, это не сбой. Доменные состояния: not_ready — типы не настроены; schema_unavailable — источник типов не синхронизирован.

Доступ: чтение · Списковый: нет · Версии контракта: 1

Аргументы

Аргументов нет.

Данные ответа (data)

ПолеПри успехеТипЧто это
typesдасписок MeetingType
errorнетDomainErrorДоменное состояние
fallback_type_idнетstring
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol-types",
      "label": "Типы встреч"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 3600,
    "stale": false
  },
  "data": {
    "types": [
      {
        "id": "mt-standup",
        "name": "Планёрка",
        "aliases": [
          "планёрка",
          "планерка",
          "standup",
          "дейли"
        ],
        "unit_id": "u-sales",
        "membership_kind": "unit",
        "hint": {
          "text": "В протоколе планёрки обязательны разделы «Решения» и «Поручения» с ответственным и сроком по каждому пункту.",
          "mode": "insert"
        },
        "description": "Короткая встреча отдела по текущим задачам."
      },
      {
        "id": "mt-client",
        "name": "Встреча с клиентом",
        "aliases": [
          "клиент",
          "встреча с клиентом",
          "презентация"
        ],
        "membership_kind": "pool",
        "hint": {
          "text": "Протокол встречи с клиентом оформляется письмом клиенту: обращение, договорённости, следующие шаги, подпись менеджера.",
          "mode": "replace"
        }
      },
      {
        "id": "mt-retro",
        "name": "Ретроспектива",
        "aliases": [
          "ретро",
          "retro"
        ]
      }
    ],
    "fallback_type_id": "mt-standup"
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol-types"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "not_ready",
      "message": "Типы встреч не настроены: заведите их в кабинете.",
      "retryable": false
    }
  }
}

norm_protocols_list

Протоколы компании страницами, от свежих к старым по дате встречи. Фильтры: from и to — дни встречи включительно; status — одно из значений контракта; unit_id — подразделение по прямому совпадению, без спуска в дочерние; meeting_ids — до 200 идентификаторов встреч: протокол есть в ответе — значит существует, так один вызов заменяет пакетную проверку «обработано ли». Без include_deleted удалённые человеком протоколы не отдаются. Тело протокола в списке не едет — оно велико, берите norm_protocol_get. total — сколько подошло под фильтр до применения страницы. Для следующей страницы передайте page.next_cursor как cursor. Доменное состояние not_ready — протоколы у компании не настроены.

Доступ: чтение · Списковый: да · Версии контракта: 1

Аргументы

ПолеОбязательноТипЧто это
cursorнетstring
fromнетstring (date)
include_deletedнетboolean
limitнетinteger
meeting_idsнетсписок string
statusнетProtocolStatusСтатус протокола
toнетstring (date)
unit_idнетstring

Данные ответа (data)

ПолеПри успехеТипЧто это
protocolsдасписок Protocol
totalдаinteger
errorнетDomainErrorДоменное состояние
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocols:2026-09",
      "label": "Протоколы за сентябрь"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 300,
    "stale": false
  },
  "page": {
    "has_more": true,
    "next_cursor": "eyJvZmZzZXQiOjJ9"
  },
  "data": {
    "protocols": [
      {
        "id": "prt-2031",
        "meeting_id": "01K9F2QH7T8ZRC4M0X5B2VNJ3D",
        "title": "Планёрка отдела продаж 2026-09-21",
        "status": "done",
        "participant_ids": [
          "p-1042",
          "p-1077"
        ],
        "deleted": false,
        "meeting_date": "2026-09-21",
        "organizer_id": "p-1042",
        "unit_id": "u-sales",
        "type_id": "mt-standup",
        "url": "https://records.example.com/prt-2031",
        "updated_at": "2026-09-21T11:02:00.000Z"
      },
      {
        "id": "prt-2028",
        "meeting_id": "01K9EZZC2P4NM6S1VB8H3TQXWR",
        "title": "Встреча с клиентом «Актив»",
        "status": "draft",
        "participant_ids": [
          "p-1042"
        ],
        "participant_emails": [
          "s.ilin@example.com"
        ],
        "deleted": false,
        "meeting_date": "2026-09-19",
        "url": "https://records.example.com/prt-2028"
      }
    ],
    "total": 7
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocols"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "page": {
    "has_more": false
  },
  "data": {
    "error": {
      "code": "not_ready",
      "message": "База протоколов не подключена: настройте её в кабинете.",
      "retryable": false
    }
  }
}

norm_protocol_get

Протокол одной встречи по meeting_id целиком: ядро, тело, дополнительные поля, ссылка. Удалённый человеком протокол отдаётся с deleted: true — воссоздавать его нельзя. Тело реализация обрезает так, чтобы ответ уложился в предел размера, и тогда ставит body_truncated: true: обрезанное тело не принимайте за полное. Доменные состояния: no_data — протокола по этой встрече нет, можно создавать (повтор ничего не изменит); not_ready — протоколы не настроены.

Доступ: чтение · Списковый: нет · Версии контракта: 1

Аргументы

ПолеОбязательноТип
meeting_idдаstring

Данные ответа (data)

ПолеПри успехеТипЧто это
body_truncatedдаboolean
protocolдаProtocolПротокол встречи
errorнетDomainErrorДоменное состояние
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol:01K9F2QH7T8ZRC4M0X5B2VNJ3D",
      "label": "Карточка протокола"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 300,
    "stale": false
  },
  "data": {
    "protocol": {
      "id": "prt-2031",
      "meeting_id": "01K9F2QH7T8ZRC4M0X5B2VNJ3D",
      "title": "Планёрка отдела продаж 2026-09-21",
      "status": "done",
      "participant_ids": [
        "p-1042",
        "p-1077"
      ],
      "deleted": false,
      "meeting_date": "2026-09-21",
      "source_url": "https://meet.example.com/rec/01K9F2QH7T8ZRC4M0X5B2VNJ3D",
      "organizer_id": "p-1042",
      "agenda": "1. Воронка недели. 2. Блокеры по «Активу».",
      "unit_id": "u-sales",
      "type_id": "mt-standup",
      "body": "## Решения\n\n- Перенести демо для «Актива» на 25.09.\n\n## Поручения\n\n- Илин: подготовить смету до среды.",
      "url": "https://records.example.com/prt-2031",
      "updated_at": "2026-09-21T11:02:00.000Z",
      "extra": {
        "decision_owner": "p-1042"
      }
    },
    "body_truncated": false
  }
}
Пример: случай «deleted»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol:01K9EZZC2P4NM6S1VB8H3TQXWR",
      "label": "Карточка протокола"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 300,
    "stale": false
  },
  "data": {
    "protocol": {
      "id": "prt-2028",
      "meeting_id": "01K9EZZC2P4NM6S1VB8H3TQXWR",
      "title": "Встреча с клиентом «Актив»",
      "status": "draft",
      "participant_ids": [
        "p-1042"
      ],
      "deleted": true,
      "meeting_date": "2026-09-19"
    },
    "body_truncated": false
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol:01K9G000000000000000000000"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "no_data",
      "message": "Протокола по этой встрече ещё нет: можно создавать.",
      "retryable": false
    }
  }
}

norm_protocol_upsert

Создать или переписать протокол встречи: ядро полей плюс тело в markdown. Состав полей задан контрактом — читать схему перед записью не нужно. Идемпотентно по meeting_id: повторный вызов переписывает ТУ ЖЕ карточку (created: false). Тело заменяется целиком, поля ядра объединяются: поля нет во входе — оно не трогается; переданный массив заменяет прежний набор; null у одиночного поля очищает его; внутри extra то же правило по каждому ключу. Статус, который человек поставил в системе компании вне значений контракта, не затирается — поле вернётся в kept_existing; реализация вправе защищать так и другие поля. Запись создаётся ДАЖЕ если обязательное для компании поле пустое — отражайте незавершённость статусом draft, а не отказом. Непринятое поле не отменяет операцию: оно приедет в rejected_fields успешного ответа, там же unresolved_people — почты участников и организатора без учётной записи в системе компании. Идентификаторы людей берите в norm_people_list; тип и подразделение — из norm_protocol_types. Доменные состояния: not_ready — запись протоколов не настроена; record_deleted — карточку удалил человек, воссоздавать нельзя; record_rejected — хранилище отвергло карточку целиком, повтор даст то же; unknown_field — компания не ведёт поле ядра; temporary и rate_limited — повторите позже. Реализация вправе разрешить запись только привилегированным ролям и отвечать unauthorized_scope.

Доступ: запись · Списковый: нет · Версии контракта: 1

Аргументы

ПолеОбязательноТипЧто это
bodyдаstring
meeting_idдаstring
agendaнетstring | null
extraнетobject
meeting_dateнетstring (date)
organizer_emailнетstring
organizer_idнетstring | null
participant_emailsнетсписок string
participant_idsнетсписок string
source_urlнетstring (uri)
statusнетProtocolStatusСтатус протокола
titleнетstring
type_idнетstring | null
unit_idнетstring | null

Данные ответа (data)

ПолеПри успехеТипЧто это
createdдаboolean
idдаstring
kept_existingдасписок string
rejected_fieldsдасписок RejectedField
unresolved_peopleдасписок string
errorнетDomainErrorДоменное состояние
noteнетstring
urlнетstring (uri)
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol:01K9F2QH7T8ZRC4M0X5B2VNJ3D",
      "label": "Карточка протокола"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:31:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "id": "prt-2031",
    "created": false,
    "url": "https://records.example.com/prt-2031",
    "rejected_fields": [
      {
        "key": "extra.duration",
        "reason": "вычисляемое свойство: значение задаёт хранилище"
      }
    ],
    "unresolved_people": [
      "s.ilin@example.com"
    ],
    "kept_existing": [
      "status"
    ]
  }
}
Пример: случай «created»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol:01K9EZZC2P4NM6S1VB8H3TQXWR",
      "label": "Карточка протокола"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:31:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "id": "prt-2032",
    "created": true,
    "url": "https://records.example.com/prt-2032",
    "rejected_fields": [],
    "unresolved_people": [],
    "kept_existing": []
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "protocol:01K9EZZC2P4NM6S1VB8H3TQXWR"
    }
  ],
  "freshness": {
    "as_of": "2026-09-22T09:31:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "record_deleted",
      "message": "Протокол этой встречи удалил человек. Создавать его заново нельзя — это его решение.",
      "retryable": false
    }
  }
}

Объекты семейства

Объекты, из которых состоят аргументы и ответы инструментов этого семейства.

MeetingType

Тип встречи. Категория встречи, которую заводит компания: планёрка, ретро, встреча с клиентом. aliases — написания в названиях встреч для детерминированного распознавания. unit_id — подразделение за типом; membership_kind pool — тип объединяет людей из разных подразделений. Нет поля hint — подсказки нет. truncated: true — подсказка обрезана, применять её нельзя.

ПолеОбязательноТипЧто это
idдаstring
nameдаstring
aliasesнетсписок string
descriptionнетstring
hintнетMeetingTypeHintПодсказка типа встречи
membership_kindнетunit | pool
truncatedнетboolean
unit_idнетstring

MeetingTypeHint

Подсказка типа встречи. Текст, который компания просит учесть в протоколе встречи этого типа. insert — вставка внутрь своего каркаса; replace — самостоятельная инструкция со своим форматом, вкладывать её внутрь каркаса нельзя.

ПолеОбязательноТип
modeдаinsert | replace
textдаstring

ProtocolStatus

Статус протокола. draft — черновик, есть незаполненное; done — готов; no_meeting — встречи не было. Значение, поставленное человеком вне этого списка, агент не меняет: сервер оставляет его и называет поле в kept_existing.

Значения: draft, done, no_meeting.

Protocol

Протокол встречи. Карточка итогов одной встречи. id — карточка в системе компании, meeting_id — встреча из norm_meetings_list и ключ идемпотентности. participant_ids — сотрудники из norm_people_list; participant_emails — почты тех, для кого сотрудника не нашлось. deleted — карточку удалил человек. body в списке не отдаётся, в чтении может быть обрезано (смотрите body_truncated). extra — поля, которые компания ведёт сама, та же форма во входе записи.

ПолеОбязательноТипЧто это
deletedдаboolean
idдаstring
meeting_idдаstring
participant_idsдасписок string
statusдаProtocolStatusСтатус протокола
titleдаstring
agendaнетstring
bodyнетstring
extraнетobject
meeting_dateнетstring (date)
organizer_idнетstring
participant_emailsнетсписок string
source_urlнетstring (uri)
type_idнетstring
unit_idнетstring
updated_atнетstring (date-time)
urlнетstring (uri)

RejectedField

Непринятое поле. Поле, которое запись не приняла, и причина. Операция при этом выполнена.

ПолеОбязательноТип
keyдаstring
reasonдаstring