Skip to content

Семейство: records

norm_record_find

Есть ли уже записи по этим ключам — спрашивайте пакетом до 200 ключей за вызов, а не по одной. Так узнают, что уже обработано: своего списка обработанного у потребителя нет. Ответ идёт в том же порядке, что и запрос. exists: false — записи нет, можно создавать. exists: true вместе с deleted: true — запись была и её удалил человек: создавать заново нельзя. Пустой индекс — не ошибка, просто все ключи exists: false.

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

Вход

ПолеОбязательноТипЗначение
keysдасписок string
targetнетstring

Данные ответа

ПолеПри успехеТипЗначение
errorнетDomainErrorДоменное состояние
recordsдасписок FoundRecord
targetдаstring
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:index:meeting-protocols",
      "label": "Индекс записей"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T09:30:00.000Z",
    "ttl_sec": 86400,
    "stale": false
  },
  "data": {
    "target": "meeting-protocols",
    "records": [
      {
        "key": "meeting_protocol:01K9F2QH7T8ZRC4M0X5B2VNJ3D",
        "exists": false
      },
      {
        "key": "meeting_protocol:01K9F0YB3M6QA8T2WD7E4RSKPN",
        "exists": true,
        "url": "https://records.example.com/01K9F0YB3M6QA8T2WD7E4RSKPN"
      },
      {
        "key": "meeting_protocol:01K9EZZC2P4NM6S1VB8H3TQXWR",
        "exists": true,
        "deleted": true
      }
    ]
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:index"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "unknown_target",
      "message": "Настроено несколько целей записи — укажите ярлык в аргументе target.",
      "retryable": false,
      "allowed_targets": [
        "meeting-protocols",
        "meeting-protocols-staging"
      ]
    }
  }
}

norm_record_hint

Подсказка под ОДИН выбранный вариант поля: текст, который компания просит учесть, когда значение поля именно такое. Спрашивайте только для варианта, который уже выбрали, и один раз за прогон на повторяющийся вариант. В описании записи этих текстов нет намеренно: они не влезают в один ответ, поэтому там остаётся только признак has_hint. Поля hint в ответе нет — у варианта подсказки нет, это нормально: собирайте на своём каркасе. truncated: true — текст обрезан, НЕ применяйте его: отрезан конец, где обычно и лежат требования.

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

Вход

ПолеОбязательноТипЗначение
fieldдаstring
optionдаstring
targetнетstring

Данные ответа

ПолеПри успехеТипЗначение
errorнетDomainErrorДоменное состояние
fieldдаstring
hintнетRecordHintПодсказка под вариант
optionдаstring
targetдаstring
truncatedдаboolean
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:hint:f-type:o-weekly",
      "label": "Подсказка"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T03:00:00.000Z",
    "ttl_sec": 86400,
    "stale": false
  },
  "data": {
    "target": "meeting-protocols",
    "field": "f-type",
    "option": "o-weekly",
    "truncated": false,
    "hint": {
      "text": "Протокол планёрки: сначала решения списком, затем поручения с исполнителем и сроком, в конце вопросы без ответа.",
      "mode": "replace"
    }
  }
}
Пример: случай «ok_no_hint»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:hint:f-type:o-top"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T03:00:00.000Z",
    "ttl_sec": 86400,
    "stale": false
  },
  "data": {
    "target": "meeting-protocols",
    "field": "f-type",
    "option": "o-top",
    "truncated": false
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:hints"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "schema_unavailable",
      "message": "Цель настроена, но её описание ещё не прочитано: источник не синхронизирован.",
      "retryable": true
    }
  }
}

norm_record_schema

Из чего состоит карточка целевой записи: поля, их типы, что обязательно и какие значения допустимы. Спрашивайте ПЕРЕД тем как заполнять запись — состав полей у каждой компании свой. У поля бывает роль — объявленный смысл из словаря вида цели: такое поле заполняется прямо из данных предмета. Поле без роли предметное, его значение выбирается из вариантов по опорным признакам. Идентификаторы людей для полей типа person берите в norm_people_list. Свойства, не отобразившиеся в шесть типов, перечислены в skipped с причиной — это не сбой. Доменные состояния: not_ready ждёт человека, schema_unavailable — источник не синхронизирован, unknown_target — ярлык неизвестен, со списком допустимых.

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

Вход

ПолеОбязательноТипЗначение
targetнетstring

Данные ответа

ПолеПри успехеТипЗначение
errorнетDomainErrorДоменное состояние
fieldsдасписок RecordField
kindдаRecordKindВид цели записи
skippedдасписок SkippedField
targetдаstring
warningsнетсписок string
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:schema:meeting-protocols",
      "label": "Описание карточки"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T03:00:00.000Z",
    "ttl_sec": 86400,
    "stale": false
  },
  "data": {
    "target": "meeting-protocols",
    "kind": "meeting_protocol",
    "fields": [
      {
        "key": "f-title",
        "name": "Название",
        "type": "text",
        "required": true,
        "role": "title"
      },
      {
        "key": "f-date",
        "name": "Дата встречи",
        "type": "date",
        "required": true,
        "role": "meeting_date"
      },
      {
        "key": "f-link",
        "name": "Ссылка на запись",
        "type": "url",
        "required": false,
        "role": "source_url"
      },
      {
        "key": "f-people",
        "name": "Участники",
        "type": "person",
        "required": false,
        "role": "participants"
      },
      {
        "key": "f-owner",
        "name": "Организатор",
        "type": "person",
        "required": false,
        "role": "organizer"
      },
      {
        "key": "f-agenda",
        "name": "Повестка",
        "type": "text",
        "required": false,
        "role": "agenda"
      },
      {
        "key": "f-status",
        "name": "Статус",
        "type": "choice_one",
        "required": true,
        "role": "status",
        "closed": true,
        "options": [
          {
            "id": "o-draft",
            "name": "Черновик",
            "role": "draft",
            "has_hint": false
          },
          {
            "id": "o-done",
            "name": "Готово",
            "role": "done",
            "has_hint": false
          },
          {
            "id": "o-none",
            "name": "Встречи не было",
            "role": "no_meeting",
            "has_hint": false
          },
          {
            "id": "o-cancel",
            "name": "Отменено",
            "has_hint": false
          }
        ]
      },
      {
        "key": "f-type",
        "name": "Тип встречи",
        "type": "choice_one",
        "required": false,
        "closed": true,
        "fallback_hint_option_id": "o-weekly",
        "options": [
          {
            "id": "o-weekly",
            "name": "Планёрка",
            "aliases": [
              "планёрка",
              "еженедельная"
            ],
            "org_unit_id": "u-sales",
            "has_hint": true,
            "description": "Регулярная встреча подразделения по текущим задачам"
          },
          {
            "id": "o-top",
            "name": "Руководители",
            "membership_kind": "pool",
            "members": [
              "a.novikova@example.com",
              "s.ilin@example.com"
            ],
            "has_hint": false
          }
        ]
      }
    ],
    "skipped": [
      {
        "name": "Длительность",
        "type": "формула",
        "reason": "вычисляемое свойство в контракт не отображается"
      }
    ],
    "warnings": []
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:schema"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "unknown_target",
      "message": "Ярлык цели «протоколы» неизвестен. Запись в цель по умолчанию не выполняется.",
      "retryable": false,
      "allowed_targets": [
        "meeting-protocols",
        "meeting-protocols-staging"
      ]
    }
  }
}

norm_record_targets

Куда вообще можно писать записи: ярлыки целей, названия для человека и вид карточки. Ярлык отсюда передаётся аргументом target в остальные глаголы записи. Спрашивайте, когда цель неизвестна или их может быть несколько. Доменное состояние not_ready — ни одной цели не настроено: это ждёт человека, повторный вызов ничего не изменит.

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

Вход

ПолеОбязательноТипЗначение

Данные ответа

ПолеПри успехеТипЗначение
errorнетDomainErrorДоменное состояние
targetsдасписок RecordTarget
Пример: успешный ответ
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:targets",
      "label": "Цели записи"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T03:00:00.000Z",
    "ttl_sec": 86400,
    "stale": false
  },
  "data": {
    "targets": [
      {
        "id": "meeting-protocols",
        "name": "Протоколы встреч",
        "kind": "meeting_protocol"
      }
    ]
  }
}
Пример: случай «domain_error»
json
{
  "source_refs": [
    {
      "source": "company-data",
      "ref": "record:targets"
    }
  ],
  "freshness": {
    "as_of": "2026-09-21T09:30:00.000Z",
    "ttl_sec": 0,
    "stale": false
  },
  "data": {
    "error": {
      "code": "not_ready",
      "message": "Ни одна цель записи не настроена: не задано, куда писать карточки. Это ждёт человека.",
      "retryable": false
    }
  }
}

norm_record_upsert

Создать или переписать запись в системе компании: поля карточки плюс тело в markdown. Идемпотентно по key: повторный вызов с тем же ключом переписывает ТУ ЖЕ запись. Поля берите из norm_record_schema. Тело заменяется целиком, поля объединяются: непереданное поле остаётся как было, а поле, где уже есть значение человека, не затирается (оно вернётся в kept_existing). Запись создаётся ДАЖЕ если обязательное поле пустое — отражайте незавершённость статусом, а не отказом от записи. Непринятое поле не отменяет операцию: оно приедет в rejected_fields успешного ответа, там же unresolved_people — люди без учётной записи в системе компании. Доменные состояния: record_deleted — запись удалил человек, воссоздавать нельзя; record_rejected — хранилище отклонило запись по форме, повтор даст тот же ответ; temporary и rate_limited — повторите позже; not_ready и schema_unavailable ждут человека или синхронизации.

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

Вход

ПолеОбязательноТипЗначение
bodyдаstring
fieldsнетсписок FieldValue
keyдаstring
targetнетstring
titleнетstring

Данные ответа

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