Создание форм
Как организация создаёт, проверяет, заменяет и архивирует свои формы целиком через API или ИИ-агента: дерево из шапки, страниц и элементов в одном вызове.
О чём речь
Форма это дерево: шапка (название, краткое имя, цель, обращение, согласия), страницы и элементы на них (текст, стандартное поле, собственное поле, матрица, повторяющаяся группа). Она строится одним вызовом, а не по элементам; новые собственные поля создаются попутно. Цель PROSPECT (отправки становятся потенциальными клиентами) или CLIENT_RECORD (анкеты карты клиента, только с лицензионным правом на практику). Все эндпоинты создания требуют человека с ролью администратора организации; чтение и пробный запуск требуют forms:read, создание, замена, настройки, логотип лицензии, ссылка для распространения и архивирование forms:write. Персональной ссылке не нужна роль администратора, но дополнительно нужен contacts:write.
1. Получить строительные блоки
GET /forms/building-blocks?targetEntity=PROSPECT называет стандартные поля (key и их имя в условиях: inConditions), существующие собственные поля организации с кратким именем (slug), типом и вариантами, типы для новых полей, язык условий и устройство матрицы и повторяющейся группы. Существующее собственное поле используется по его slug, а не создаётся заново.
curl "https://www.claritos.io/api/v1/forms/building-blocks?targetEntity=PROSPECT" \
-H "Authorization: Bearer capi_…"2. Описать дерево
pages[].elements[] с kind: text (content), standardField (field = key из шага 1), field (field = slug; с new поле создаётся: label, type, options), matrix и repeater (key, config). Каждое поле может иметь required, question, placeholder и condition; condition это выражение над полями ВЫШЕ, например sleep == 'poor'. Поля с одинаковым row стоят рядом, weight делит ширину. Согласия: consentMode none, optional или promotion; consents.marketing.email и .sms с собственным текстом или ORGANIZATION для текста организации, consents.additional для ещё двух флажков. Самому запросу флажок не нужен; форма показывает уведомление о защите данных.
{
"targetEntity": "PROSPECT",
"name": "Vorab-Check Schlaf",
"slug": "vorab-check-schlaf",
"addressForm": "SIE",
"consentMode": "none",
"pages": [
{
"title": "Vor Ihrem Termin",
"elements": [
{ "kind": "standardField", "field": "firstName", "required": true, "row": "name" },
{ "kind": "standardField", "field": "lastName", "required": true, "row": "name" },
{ "kind": "standardField", "field": "email", "required": true },
{ "kind": "field", "field": "schlaf", "required": true,
"new": { "label": "Wie schlafen Sie?", "type": "SELECT", "options": ["gut", "mittel", "schlecht"] } },
{ "kind": "field", "field": "schlaf_notiz", "condition": "schlaf == 'schlecht'",
"new": { "label": "Was stört Ihren Schlaf?", "type": "TEXTAREA" } }
]
}
]
}3. Пробный запуск
POST /forms/validate проверяет дерево так же, как при создании, ничего не сохраняя, и всегда отвечает 200: valid, errors с путём (например body.pages.0.elements.3.field, счёт с 0), кодом и фразой, а также notes и поля, которые будут созданы (createdFields) или использованы повторно (reusedFields). Уже занятое краткое имя появляется здесь как ошибка с кодом form-slug-taken в body.slug. Зелёный результат означает: создание пройдёт.
curl -X POST https://www.claritos.io/api/v1/forms/validate \
-H "Authorization: Bearer capi_…" -H "Content-Type: application/json" \
-d @vorab-check.json{ "valid": true, "errors": [], "notes": [], "slug": "vorab-check-schlaf",
"pages": 1, "elements": 5, "createdFields": ["schlaf", "schlaf_notiz"], "reusedFields": [] }4. Создать
POST /forms создаёт форму и отвечает 201 с описанием как в GET /forms/{id}, а также build с createdFields, reusedFields и notes. Ошибки в дереве приходят как 422 validation-failed с теми же путями, что и в пробном запуске, занятое краткое имя как 409 с reason form-slug-taken. Idempotency-Key не даёт создать вторую форму при повторном вызове.
curl -X POST https://www.claritos.io/api/v1/forms \
-H "Authorization: Bearer capi_…" -H "Content-Type: application/json" \
-H "Idempotency-Key: <eindeutig>" -d @vorab-check.json5. Заменить целиком
PUT /forms/{id} принимает то же тело и заменяет дерево. Всё, чего нет в теле, считается значением по умолчанию, а не прежним значением: всегда отправляйте всё дерево, лучше всего построенное из GET /forms/{id}. То, чего тело не знает (доступы, ссылки, страница завершения, отображение), сохраняется; это меняет PATCH (раздел 6). Страницы сохраняются по позиции, отправки остаются доступными для чтения. Цель изменить нельзя (422 в body.targetEntity); архивированная форма отвечает 409 с reason archived.
curl -X PUT https://www.claritos.io/api/v1/forms/<FORMULAR> \
-H "Authorization: Bearer capi_…" -H "Content-Type: application/json" \
-d @vorab-check.json6. Настройки и ссылка для распространения
PATCH /forms/{id} меняет только настройки, а не дерево: name, addressForm, allowMultiple, publicAccessEnabled (публичная ссылка), availableInPortal, consentMode, отображение (showProgress, showSummary, showFieldLabels, showClientHeader), reminderService, recognitionCard, translateResponses, thirdPartyMode, addressFinderMode и addressFinderPlaceholder, licenseLabel и completion. Всё отсутствующее сохраняется; имена те же, что в GET /forms/{id}, а ответ это описание формы. completion заменяет всё завершение целиком, null возвращает стандартный текст. Краткое имя, цель, страницы и согласия задаёт только PUT; при передаче ответ 422 invalid_combination. Ссылку организации для распространения читает GET /forms/{id}/share-link (url равен null, пока ссылка не создана или публичная ссылка выключена). POST /forms/{id}/share-link создаёт её и при каждом следующем вызове возвращает ту же; если публичная ссылка выключена, ответ 409 с reason public-access-disabled. Ссылки партнёров здесь не появляются никогда: каждая отправка через них приписывалась бы партнёру. Логотип лицензии загружается в два шага: POST /forms/{id}/license-logo/upload возвращает uploadUrl, uploadHeaders и storageKey; файл (PNG, JPEG, WebP или SVG, не более 2 МБ) отправляется через PUT на uploadUrl; затем POST /forms/{id}/license-logo/confirm подтверждает его с storageKey. Только после этого форма показывает логотип (licenseLogoUrl в GET /forms/{id}); если файла ещё нет, confirm отвечает 422 в body.storageKey. DELETE /forms/{id}/license-logo удаляет его.
curl -X PATCH https://www.claritos.io/api/v1/forms/<FORMULAR> \
-H "Authorization: Bearer capi_…" -H "Content-Type: application/json" \
-d '{ "publicAccessEnabled": true, "showSummary": true, "completion": { "title": "Danke!" } }'curl -X POST https://www.claritos.io/api/v1/forms/<FORMULAR>/share-link \
-H "Authorization: Bearer capi_…"7. Персональная ссылка
POST /forms/{id}/personal-links выдаёт ссылку для конкретного человека, например по визитной карточке на выставочном стенде. values содержит его данные с ключами std:, как при отправке; нужен хотя бы std:email, std:firstName или std:lastName, иначе 422 invalid_combination в body.values. Контакт при этом создаётся или находится по тому же правилу дубликатов, что и при отправке; пустые поля дополняются, ничего не перезаписывается. Форма показывает только переданные значения, ничего из уже сохранённого у контакта. Ответ 201 с url, contactId и validUntil (семь дней); каждый вызов это новая ссылка. documentId привязывает документ организации (например, фото карточки) к контакту, если он ещё никому не присвоен; неизвестный документ даёт 422 invalid_reference. Только для форм с целью PROSPECT, иначе 409 с reason target-not-supported. Права forms:write и contacts:write, без роли администратора.
curl -X POST https://www.claritos.io/api/v1/forms/<FORMULAR>/personal-links \
-H "Authorization: Bearer capi_…" -H "Content-Type: application/json" \
-d '{ "values": { "std:firstName": "Anna", "std:lastName": "Muster", "std:email": "anna@example.com" } }'{ "url": "https://www.claritos.io/f/Zk3q…", "contactId": "cmf2contact00000000000001", "validUntil": "2026-11-03T10:00:00.000Z" }8. Архивировать и вернуть
POST /forms/{id}/archive и POST /forms/{id}/unarchive отвечают 200 с формой; повторный вызов ничего не меняет. Архивированная форма не принимает отправки; замена, изменение настроек, логотип лицензии, ссылка для распространения и персональная ссылка отвечают 409 с reason archived, пока её не вернут.
С ИИ-агентом
Через API-MCP тот же путь: сначала это руководство, затем строительные блоки, повторять пробный запуск, пока valid не станет true, и только потом создавать. Для изменений дерева заново построить его из описания и заменить целиком; только настройки меняет forms.updateSettings, без дерева.
{ "name": "guide", "arguments": { "topic": "form-building" } }
{ "name": "call_endpoint", "arguments": { "id": "forms.buildingBlocks", "query": { "targetEntity": "PROSPECT" } } }
{ "name": "call_endpoint", "arguments": { "id": "forms.validate", "body": { … } } }
{ "name": "call_endpoint", "arguments": { "id": "forms.create", "body": { … }, "idempotencyKey": "…" } }