Быстрый старт
1. Проверить подключение
Подставьте HTTPS-домен своей организации и токен. Как получить токен. Пример использует Bash, curl и jq.
export SERVICEAPP_ORIGIN='https://organization.example'
export SERVICEAPP_TOKEN='<SERVICEAPP_TOKEN>'
export API="$SERVICEAPP_ORIGIN/api/v1"
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header 'Accept: application/json' \
"$API/context" | jq .
Центральный сайт и домен другой организации не подходят. Укажите адрес без завершающего /.
Проверьте data.access.status, data.features.public_api, data.scopes, data.workshop_ids, data.timezone и data.currency. Для действующего токена контекст доступен также при отключённом API или завершившейся подписке. При недействительном токене он вернёт 401.
Подготовить доступ к остальным методам
Понадобятся Bash, curl и jq. В панели вашей организации откройте «Настройки → Каналы связи и интеграции → API», создайте персональное подключение, выберите разрешения подключения и мастерские, задайте срок действия. Сохраните показанный один раз секрет. Раздел доступен с правом «Системные настройки → Информация о компании»; подключение выполняет команды от имени создавшего его сотрудника. Для примера нужны customers:read, customers:write и соответствующие права сотрудника.
API должен быть включён для организации. Поддерживаются «Энтерпрайз», «Энтерпрайз Про» и действующий trial. Полные правила доступа.
2. Прочитать список клиентов
curl --fail-with-body --silent --show-error --globoff --get \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header 'Accept: application/json' \
--data-urlencode 'page[size]=10' \
--data-urlencode 'sort=id' \
"$API/customers" | jq .
Следующая страница находится в links.next; конец обхода — meta.has_more=false и links.next=null. include, номер страницы и offset не поддерживаются. Параметры клиентов.
3. Создать клиента
Сохраните тело и ключ до отправки. Этот ключ относится к одному действию в пределах подключения; при сетевом сбое повторите тот же запрос с тем же телом и ключом. Для создания другого клиента выберите новый ключ.
cat > customer-create.json <<'JSON'
{
"name": "Демонстрационный клиент",
"phone": "+79990000001",
"email": "integration@example.com",
"external_id": "demo-customer-001"
}
JSON
export CUSTOMER_CREATE_KEY='demo:customer:create:001'
curl --fail-with-body --silent --show-error --request POST \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: $CUSTOMER_CREATE_KEY" \
--data-binary '@customer-create.json' \
--dump-header customer-create.headers \
--output customer-response.json \
"$API/customers"
jq . customer-response.json
export CUSTOMER_ID="$(jq -r '.data.id' customer-response.json)"
export OPERATION_ID="$(jq -r '.meta.operation_id' customer-response.json)"
Ожидается 201. Ответ содержит карточку в data, запись об операции meta.operation_id, изменённые ресурсы meta.affected_resources и предупреждения meta.warnings. Заголовок Location ведёт на операцию. Повтор того же принятого запроса возвращает сохранённый 201 и Idempotency-Replayed: true, без создания второго клиента.
external_id уникален для этого типа ресурса в текущем подключении. Он дополняет Idempotency-Key. ИНН, КПП, банковские реквизиты и серийные номера передаются строками с сохранением ведущих нулей.
4. Изменить клиента с проверкой версии
Сначала прочитайте актуальную карточку. Версия из ответа создания могла устареть.
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--dump-header customer-get.headers \
--output customer-current.json \
"$API/customers/$CUSTOMER_ID"
export RESOURCE_VERSION="$(jq -r '.data.version' customer-current.json)"
export CUSTOMER_UPDATE_KEY='demo:customer:update:001'
cat > customer-update.json <<'JSON'
{"address":"Демонстрационный город, Тестовая улица, дом 1"}
JSON
curl --fail-with-body --silent --show-error --request POST \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: $CUSTOMER_UPDATE_KEY" \
--header "If-Resource-Version: $RESOURCE_VERSION" \
--data-binary '@customer-update.json' \
"$API/customers/$CUSTOMER_ID/update" | jq .
Версия передаётся без кавычек, ровно как получена в data.version. ETag из заголовка GET сюда не подставляется. При 412 перечитайте карточку и согласуйте изменение; изменённое действие отправляйте с новым ключом. При потере ответа повторите исходную команду с сохранённой версией и ключом.
5. Проверить исход по журналу
curl --fail-with-body --silent --show-error \
--header "Authorization: Bearer $SERVICEAPP_TOKEN" \
"$API/api-operations/$OPERATION_ID" | jq .
Для журнала нужен api_operations:read. Если ответ первой команды потерян и ID операции неизвестен, повторите исходный POST с прежним ключом. GET журнала читает исход, не исполняя команду повторно. Все состояния и правила опрос состояния.
После знакомства выполните создание акта и ТО с выездом. Общий формат ошибок помогает различать исправление данных, конфликт версии и неопределённый исход.