Fiqo · JSON API кроссов
Схема v1 · отдельный сервис · изоляция подписчиков · источник обязателен
Личная база + общая подтверждённая базаПоиск по бренду и артикулу
Запрос выполняется сервером клиента с API-ключом. Браузеру постоянный ключ не передаётся. Аккаунт, область ключа и подписка проверяются сервером при каждом запросе. Реальный адрес и ключ выдаются при подключении.
POST /v1/lookup
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"brand":"MANN-FILTER","article":"W 67/1","supplier":"Supplier One"}{
"schema": "fiqo.crosses", "version": 1,
"found": true,
"part": {"id":"…","brandId":"…","brand":"MANN-FILTER","article":"W 67/1"},
"crosses": [{
"id":"…", "part":{"id":"…","brand":"DEMO","article":"DF100"},
"relation":"replacement", "direction":"forward",
"origin":"shared", "status":"confirmed", "priority":"high",
"confidence":"manufacturer", "restrictions":[]
}],
"next": null
}Нормализация сохраняет дефисы, косые черты, различие кириллицы/латиницы и O/0. Варианты поставщика задаются алиасами. equivalent симметричен, replacement направлен, conditional требует списка ограничений. Транзитивные замены не выводятся.
Источники и происхождение
У кросса может быть несколько независимых свидетельств. Каждое свидетельство и каждый алиас связаны с источником и импортом: кто опубликовал данные, какой API или исходный файл, версия, внешний ID строки, исходные значения и положение в файле. SHA-256 считается на исходных байтах загруженного файла.
POST /v1/sources
{"name":"Каталог производителя","kind":"file", "publisher":"Производитель",
"externalId":"catalog-2026","scope":"private"}
POST /v1/sources/<sourceId>/artifacts?filename=crosses.csv&version=2026-10
Content-Type: application/octet-stream
<исходные байты файла>
POST /v1/sources/<sourceId>/imports
Idempotency-Key: import-2026-10-page-1
{"externalBatchId":"page-1","version":"2026-10","artifactId":"…",
"rows":[{"externalRowId":"line-15","locator":"лист 1, строка 15",
"from":{"brand":"BRAND A","article":"A-1"},
"to":{"brand":"BRAND B","article":"B-2"},"relation":"replacement"}]}Импорт возвращает HTTP 202 и ID сохраняемого задания. Результат проверяется через GET /v1/jobs/:id. Повтор внешнего ID пачки не создаёт дублей; другие данные под тем же ID отклоняются. Из API-источника нужен стабильный providerKey; URL хранится без токенов и параметров авторизации.
Общая база и согласие
useShared по умолчанию true, contribute false. Личная база используется всегда. Это две независимые настройки. Три независимых подписчика повышают приоритет кандидата, но не публикуют его. Копии одного файла, один API и одна организация не дают три независимых голоса. Проверенный администратором источник производителя сразу имеет высокий приоритет. Общую базу в первом выпуске публикует администратор.
Личные записи и исходники других клиентов не возвращаются. При отзыве согласия личные данные остаются у владельца и исключаются из общего расчёта. Публикация без оставшихся подтверждений отзывается.
Удаление источника
POST /v1/sources/<sourceId>/preview
{"operation":"delete"}
POST /v1/sources/<sourceId>/execute
Idempotency-Key: delete-source-request-1
{"confirmationToken":"<токен из предпросмотра>"}Предпросмотр показывает свидетельства, алиасы, файлы и затронутые публикации. Токен действует 10 минут и связан с пользователем и состоянием подтверждений. Если данные изменились, нужен новый предпросмотр. Удаление и отключение выполняются транзакционно через устойчивую очередь. Другие источники не удаляются. Технические идентификаторы, история заданий и минимальный аудит сохраняются; удалённые свидетельства больше не участвуют в выдаче.
Синхронизация
GET /v1/changes?cursor=…&limit=100 возвращает изменения и явные удаления. Первый снимок постраничный; пока more=true, нужно продолжать по полученному курсору. Данные и курсор сохраняются вместе. При reset=true локальный набор заменяется. Неизвестный, чужой, устаревший курсор и изменение доступа к общей базе требуют восстановления снимка.
requiresResolveRefresh=true означает, что изменились алиасы или настройки: локальные результаты разрешения бренда/артикула нужно сбросить. Курсоры переживают перезапуск; скрытые пользовательские вкладки опрашивать не нужно.
Методы
| Метод | Назначение |
|---|---|
| GET/PATCH /v1/settings | Общая база и согласие на вклад |
| GET/POST /v1/sources | Список и регистрация собственных источников |
| GET /v1/sources/:id | Исходники, файлы, строки и алиасы владельца |
| POST :id/artifacts, :id/imports | Исходный файл и импорт |
| POST :id/preview, :id/execute | Предпросмотр и задание удаления/отключения |
| GET /v1/jobs, /v1/jobs/:id | Видимая очередь и результат задания |
| POST /v1/lookup | Бренд + артикул → кроссы |
| PATCH /v1/overrides | Скрыть конкретный кросс только у себя |
| GET /v1/changes | Курсор изменений |
| GET /v1/candidates, /:id | Проверка кандидатов администратором |
| POST /v1/publish | Ручная публикация с основанием |
| PATCH /v1/independence | Связать подписчиков одной организации |
| PATCH /v1/sources/:id/trust | Проверка производителя администратором |
Администрирование — через доверенный серверный шлюз Fiqo. Обычный внешний ключ чтения/записи не получает административную роль. Для внешнего административного API нужна отдельная область crosses:admin в сервисе авторизации.
Ограничения первого выпуска
До 200 результатов поиска на страницу, до 2000 кроссов и 2000 алиасов в пачке, исходный файл до 10 МБ. Начальный снимок синхронизации ограничен 100 000 связей; больший экспорт требует отдельного задания экспорта. Реальные API поставщиков и форматы их файлов подключаются отдельными адаптерами: сервис сам не обходит сайты и не угадывает схему чужого файла.