Подключение FICO · v1
Настройте свои кабинеты поставщиков, склады и наценку в FICO. Один обработчик поиска обслуживает интерфейс, JSON, NDJSON и iframe. Новый клиент при первом входе выбирает одну или несколько схем использования; изменить выбор можно в «API и подключение».
1. Подтвердите свой домен
Собственный домен обязателен для нового клиента при любой схеме, включая работу в интерфейсе FICO. Клиент приобретает его самостоятельно. Укажите точный адрес, например https://shop.example, без пути, порта и завершающего слеша. Для поддомена подтверждается именно этот поддомен.
FICO покажет имя TXT-записи _fico-verify.shop.example и уникальное значение. Добавьте их в DNS и нажмите «Проверить DNS». Запись необходимо оставить. Владение повторно проверяется при обращении с кэшем до пяти минут; неверная запись или ошибка DNS блокируют доступ после следующей проверки. Повторная ручная проверка доступна раз в пять секунд. Для действовавших до версии 009 аккаунтов сохраняется доступ к рабочему интерфейсу; интеграционные ключи всё равно требуют подтверждённого домена.
Подтверждение домена не переносит приложение на адрес вашего сайта. При включённых кабинетах FICO создаёт адрес из имени подтверждённого основного домена: magazin.ru → magazin.fiqo.ru. Свободного ввода имени нет. Для кабинета нужен основной домен без www; дополнительные адреса встраивания подтверждаются отдельно. При совпадении имён разных доменных зон обратитесь в поддержку. API и временный iframe используют fiqo.ru, настройки — ваш кабинет.
2. Создайте API-ключ
В «API и подключение» выберите подтверждённый домен, название и срок от 1 до 365 дней. Полный ключ показывается один раз. Храните его только на сервере своего приложения: не в HTML, JavaScript браузера, URL или публичном репозитории. В FICO сохраняется хеш. Можно выпустить до десяти действующих ключей; лимиты общие для аккаунта: 30 запросов в минуту и два одновременных поиска.
Права выбираются при создании ключа; по умолчанию — поиск и временное встраивание. Права медиа включаются отдельно. Он не даёт менять поставщиков, читать их секреты или оформлять заказы. Отзыв ключа, отключение аккаунта, удаление адреса или потеря подтверждения домена отключают интеграцию. Владение доменом не доказывает сетевой источник API-запроса: IP-ограничение и mTLS в этой версии отсутствуют.
3. Поиск через REST API
POST https://fiqo.ru/api/v1/search
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"article": "W671",
"brand": "MANN-FILTER",
"scope": "selected",
"format": "json"
}Вызов выполняется сервером клиента. Постоянные ключи не принимаются из браузерных запросов с Origin. Артикул всегда трактуется как артикул; автоматического перехода к штрихкоду нет. Если бренд неизвестен, отправьте запрос без brand, выберите один из data.brands и повторите запрос с брендом. allBrands: true запрашивает предложения всех найденных брендов.
scope: "selected" использует включённых поставщиков и выбранные склады. scope: "all" проверяет все настроенные неархивные подключения и их доступные склады, включая партнёрские. Права кабинетов поставщиков остаются ограничением. Таймаут каждого поставщика берётся из «Поставщики → Настройки», по умолчанию 15 секунд.
{
"schema": "fico.search", "version": 1,
"requestId": "request-uuid", "type": "result", "complete": true,
"currency": "RUB", "branding": {"name": "FICO", "menuRequired": true},
"data": {
"article": "W671", "brand": "MANN-FILTER", "all": false,
"rows": [{
"providerId": "supplier-id", "supplier": "Поставщик",
"warehouse": "Склад", "brand": "MANN-FILTER", "article": "W 67/1",
"name": "Фильтр", "purchasePrice": 250, "salePrice": 380,
"stock": "5", "days": "1", "exact": true
}],
"brands": [], "providerTimings": [], "warnings": []
}
}Пример учебный. Неизвестная цена — null. Наличие, срок и кратность сохраняют значение источника; не считайте неизвестное значение нулём. Закупка возвращается только если она включена в настройках аккаунта. Не передавайте ответ серверного API покупателю целиком: он может содержать закупку. complete означает окончание обработки; ошибки отдельных поставщиков находятся в providerTimings и warnings, а не заменяются пустым успешным ответом.
JSON и NDJSON
format: "json" возвращает один итоговый объект. format: "ndjson" возвращает application/x-ndjson: каждый объект расположен на отдельной строке. События: start, partial, затем result или error. Читайте поток до терминального события; обрыв без него означает незавершённый поиск.
В partial.data.rows находится пачка предложений очередного ответившего поставщика, provisional: true. Итоговый result.data.rows — полный снимок: замените накопленные строки, не добавляйте его повторно. Итоговая себестоимость собственного склада может измениться, когда ответят остальные поставщики. Между повторными запросами цены и остатки могут измениться.
HTTP: 400 — параметры/JSON, 401 — ключ/доступ, 403 — домен/источник, 405 — метод, 415 — формат тела, 429 — лимит с Retry-After, 500 — ошибка обработки. До открытия потока ошибка имеет вид {"error":{"code":"...","message":"...","requestId":"..."}}; после открытия — событие error с complete: false. Не повторяйте запросы непрерывно.
4. Встроенный поиск — iframe
Добавьте и подтвердите точный HTTPS-адрес сайта. На сервере сайта запросите временный адрес встраивания:
POST https://fiqo.ru/api/v1/embed-sessions
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{"origin":"https://shop.example","language":"ru","theme":"light"}Домен должен совпадать с доменом ключа. Ответ 201 содержит url, id и expiresAt. Передайте только временный URL браузеру. Доступ действует 15 минут; после истечения получите новый URL через свой сервер. Не публикуйте постоянный ключ.
<iframe id="fico-search" title="Поиск FICO"
src="URL_FROM_YOUR_SERVER"
width="100%" height="620" referrerpolicy="no-referrer"></iframe>Сервер устанавливает Content-Security-Policy frame-ancestors для подтверждённого адреса. Встраивание на другом адресе блокируется браузером, а удалённый из настроек домен блокируется сервером. Виджет использует выбранных поставщиков/склады, отдаёт только продажные цены и не предоставляет доступ к управлению FICO.
Кнопка FICO и меню остаются видимыми. Недоступные пункты скрываются. В таблице пользователь выбирает колонки; выбор сохраняется в браузере. Выбранные товары можно передать родительскому сайту:
const frame = document.getElementById('fico-search');
window.addEventListener('message', event => {
if (event.origin !== 'https://fiqo.ru' || event.source !== frame.contentWindow) return;
const data = event.data;
if (data?.type !== 'fico.selection' || data.version !== 1 || !Array.isArray(data.items)) return;
// Validate size, fields and quantities, then pass to your own server.
// Your server must recheck prices and availability before accepting an order.
});Сообщение содержит type/schema: "fico.selection", version: 1, устойчивый для неизменённого выбора id, currency: "RUB" и items. Позиция: providerId, supplier, warehouse, brand, article, name, price, quantity. Передача сообщения сайту не означает создания заказа: подтверждение журнала или корзины выполняет система клиента. Не доверяйте ценам и количествам из браузера без своей проверки.
Корзина и JSON заказа
В полном FICO корзина открывается плавающей кнопкой справа внизу и сохраняется в аккаунте. «Отправить» пока готовит скачиваемый JSON-черновик: получатель ещё не подключён. Формат: schema: "fico.order", version: 1, id, createdAt, status: draft, currency: RUB, priceType: sale, items, total. Повторная подготовка неизменённой корзины сохраняет id. Цена фиксируется при добавлении и требует проверки перед покупкой. Позиции без цены имеют null и не входят в итог.
Отдельные подписки API
Фотографии и кроссы — два независимых сервиса. Подписка FICO сама по себе их не включает. В кабинете «API и подключение» видны доступ и окончание каждой подписки; администратор меняет их отдельно в разделе «Подписки». При истечении срока соответствующий API возвращает HTTP 402. Существующие опубликованные изображения продолжают открываться по постоянным URL. Стоимость не утверждена, онлайн-оплата отключена — пока не купить.
Постоянные ключи разрешены только серверу клиента. Каждый ключ имеет свой домен, срок и права; домен подтверждается DNS TXT. Отзыв ключа и блокировка аккаунта проверяются при каждом запросе. Администратор имеет служебный доступ к API; обычный API-ключ не получает административные права общего каталога кроссов.
API кроссов
Создайте ключ «Кроссы: чтение» (crosses:read) либо «Кроссы: управление» (crosses:read + crosses:write). Публичный адрес: https://cross.fiqo.ru/v1/. Через FICO те же клиентские методы доступны по https://fiqo.ru/api/v1/crosses/. Данные и настройки разделены по клиентам.
POST https://cross.fiqo.ru/v1/lookup
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{"brand":"MANN-FILTER","article":"W 67/1","includeShared":true}Личная база используется всегда. Общий каталог включён по умолчанию; передача собственных связей в общий каталог выключена до явного согласия клиента. Эти две настройки также доступны в FICO → «API и подключение» при активной подписке на кроссы. Настройки читаются GET /v1/settings и изменяются PATCH /v1/settings: {"useShared":true,"contribute":false}. Новая импортированная связь не публикуется автоматически: общий каталог подтверждает администратор.
Для импорта создайте источник POST /v1/sources, затем отправьте POST /v1/sources/{id}/imports. Ответ 202 содержит задание; состояние — GET /v1/jobs/{id}. Повторные отправки связывайте через Idempotency-Key и externalBatchId. Для синхронизации используйте GET /v1/changes?cursor=… и сохраняйте следующий курсор вместе с данными, учитывая удаления. Бренд и артикул нормализуются по регистру и пробелам; знаки не отбрасываются и транслитерация не выполняется.
Полная схема кроссов, источников и заданий ↗. API не подтверждает наличие товара, цену или техническую совместимость. Фотографии запрашиваются отдельным API ниже.
Фотографии и медиа API
Основной адрес API: https://media.fiqo.ru/v1/. Совместимый путь через FICO: https://fiqo.ru/api/v1/media/. Права и данные одинаковы.
API возвращает постоянные HTTPS-ссылки на опубликованные JPEG / PNG. Поиск идёт сначала в личной библиотеке клиента, затем в общем каталоге подписчиков. Пополнять общий каталог может администратор. Публичная ссылка доступна каждому, кто её знает, без ключа, cookie и входа; не публикуйте приватные документы. Ссылка ведёт на конкретную версию и не имеет срока истечения.
В «API и подключение» выберите «Фото: получение ссылок» (media:read) либо «Фото: управление и ссылки» (media:read + media:write). Старые ключи поиска не получили новые права автоматически. Действуют подтверждение домена, активность аккаунта, срок и отзыв ключа. Ключ хранится только на сервере клиента.
POST https://media.fiqo.ru/v1/lookup
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{"brand":"MANN-FILTER","article":"W 67/1"}Пример структуры ответа (URL ниже условный):
{
"schema": "fico.media",
"version": 1,
"found": true,
"brand": "MANN-FILTER",
"article": "W671",
"source": "catalog",
"primaryImage": "https://media.fiqo.ru/i/IMAGE_ID/CONTENT_HASH.jpg",
"additionalImages": [],
"images": [{"url":"https://media.fiqo.ru/i/IMAGE_ID/CONTENT_HASH.jpg","primary":true,"width":1000,"height":1000}],
"revision": 12
}source: own — библиотека клиента, catalog — общий каталог. Если фотографий нет: HTTP 200, found:false, primaryImage:null, пустые списки. Наличие фотографии не означает наличие товара. Для сопоставления игнорируются регистр, пробелы и знаки в бренде/артикуле; разные слова и синонимы брендов автоматически не объединяются. Для нового товара сначала загрузите свои фотографии; API сам не скачивает изображения с сайтов поставщиков.
| Метод | Назначение |
|---|---|
| POST /api/v1/media/galleries | Создать товар: {brand,article,title?,productKey?}. Повторный код или бренд + артикул возвращает existing:true. |
| GET /api/v1/media/galleries?cursor=…&limit=100 | Личные галереи; nextCursor для следующей страницы. Фильтр productKey — внешний код товара. |
| GET /api/v1/media/galleries/{id} | Черновик, опубликованный снимок, версии и revision. |
| POST /api/v1/media/galleries/{id}/images | Бинарное тело JPEG / PNG, соответствующий Content-Type, необязательный X-Filename в encodeURIComponent. Не multipart и не JSON/base64. Для замены: ?replace=IMAGE_ID. |
| POST /api/v1/media/galleries/{id} | {action:"publish",revision} публикует текущие фото и порядок. shared:true — только администратор, явная публикация в общий каталог. |
| POST /api/v1/media/galleries/{id} | {action:"order",revision,imageIds:[…]} — все текущие ID ровно один раз. Порядок попадёт в API после publish. |
| POST /api/v1/media/galleries/{id} | {action:"delete-image",revision,imageId} или {action:"delete",revision} — удалить фото/галерею. rename меняет title. |
| GET /api/v1/media/changes?cursor=0&limit=100 | Изменения личной библиотеки, включая deleted:true. Сохраняйте nextCursor вместе с данными; пока hasMore:true, забирайте следующие страницы. |
Загрузка создаёт черновик. API продолжает возвращать предыдущий опубликованный набор до команды publish. Основное фото — первое. Предыдущие опубликованные URL сохраняются после замены, пока версия явно не удалена. Удаление делает ссылку недоступной на сервере; сторонние копии и часовой HTTP-кэш могут остаться. Одинаковые файлы хранятся один раз по SHA-256, но права и публикации разделены по аккаунтам.
Ограничения первого выпуска: 10 МБ на файл, до 12000 пикселей по стороне и 40 Мп; 30 текущих фото на товар, 5000 товаров и 200 МБ уникальных файлов на аккаунт с учётом старых версий. Медиа API: 120 запросов/минуту на аккаунт, одна загрузка одновременно. HTTP 409 — изменилась revision: перечитайте галерею; 413 — размер/квота; 415 — формат; 429 — повторите позже. Платёжная система и коммерческие тарифы здесь не добавляются: доступ проверяется по действующему аккаунту, ключу и отдельной подписке API фотографий.
Для существующих файлов на вашем сервере используйте тот же upload: прочитайте локальный файл, отправьте бинарное тело, затем publish. API не принимает пути к серверным файлам и произвольные внешние URL. Поле primaryImage можно записывать в CSV/JSON/XML прайса, additionalImages — в дополнительные колонки согласно формату площадки.
Брендинг и границы
При любом интерфейсе сохраняйте кнопку FICO и меню FICO. Готовый iframe делает это автоматически. Для собственного интерфейса через API это обязательное правило подключения; JSON сообщает branding, но не рисует элементы и технически не проверяет их присутствие. Продажа тарифов, оплата, заказ поставщику и приём заказа внешним журналом в эти методы не входят.
Ссылка → бренд и артикул → постоянная HTTPS-ссылка
Файл сохраняется на сервере FICO в личной библиотеке клиента. Временный адрес скачивания облачного диска не возвращается как ссылка для прайса. Нужны активная подписка медиа и ключ со scope media:write.
POST https://media.fiqo.ru/v1/import
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"url": "https://disk.yandex.ru/i/PUBLIC_LINK",
"brand": "MANN-FILTER",
"article": "W671"
}
Также поддерживаются публичные ссылки Google Диска вида https://drive.google.com/file/d/FILE_ID/view. Владелец должен разрешить доступ всем по ссылке и скачивание. Папки, закрытые файлы и Google-документы не импортируются. Вход в Google, CAPTCHA и ограничения владельца не обходятся.
{
"stored": true,
"brand": "MANN-FILTER",
"article": "W671",
"galleryId": "GALLERY_ID",
"imageUrl": "https://media.fiqo.ru/i/IMAGE_ID/CONTENT_HASH.jpg",
"primaryImage": "https://media.fiqo.ru/i/IMAGE_ID/CONTENT_HASH.jpg",
"additionalImages": [],
"images": [{"url":"https://media.fiqo.ru/i/IMAGE_ID/CONTENT_HASH.jpg","primary":true,"width":1200,"height":1200}],
"imported": [{"imageId":"IMAGE_ID","duplicate":false}]
}
Адреса в примере условные. imageUrl — ссылка на первое фото именно этого запроса. primaryImage и additionalImages — весь опубликованный набор товара. Для существующего товара основное фото сохраняется, новые добавляются в конец; поэтому imageUrl может отличаться от primaryImage.
Для нескольких файлов вместо url передайте urls — массив до 10 ссылок в нужном порядке. Одновременно url и urls не принимаются. В новой галерее первое фото основное. Для явной смены основного передайте primaryIndex — номер ссылки в этом запросе, начиная с 0. Разные ссылки на одинаковый файл определяются по содержимому и не создают дублей. В галерее — до 30 текущих фото, JPEG / PNG до 10 МБ на файл.
/import явно публикует только переданную партию вместе с ранее опубликованными; другие черновики галереи не публикуются. publish:false сохраняет партию черновиком без публикации, primaryIndex тогда недоступен. Если один файл недоступен, новая партия не публикуется: полученные файлы остаются черновиками, в ошибке есть galleryId. Повторите запрос — дубли не появятся, старые ссылки продолжат работать.
Предпросмотр и загрузка с компьютера
Для интерфейса с подтверждением доступны приватные предпросмотры. Они принадлежат рабочему пространству, действуют 15 минут, учитываются в квоте и не выдаются через публичные адреса. Можно держать до 10 незавершённых фото.
POST /v1/imports/previewс JSON{"url":"PUBLIC_LINK"}либо с телом JPEG / PNG и соответствующим Content-Type. Для локального файла можно передать URL-кодированное имя в X-Filename. Ответ: previewId, previewPath, filename, mime, bytes, width, height, expiresAt.GET previewPathс ключом media:read возвращает приватное изображение.POST /v1/imports/confirm:{"previewId":"PREVIEW_ID","brand":"MANN-FILTER","article":"W671"}. Для нескольких фото — previewIds вместо previewId. Ответ содержит imageUrl, imageUrls, primaryImage, additionalImages, images. Повторное подтверждение тех же фото для того же товара не создаёт дубль.POST /v1/imports/{previewId}/cancelс JSON{}убирает предпросмотр. Уже сохранённая фотография не удаляется.
В FICO → «Изображения» вставьте ссылку над таблицей, нажмите «С компьютера» либо перетащите фото в выделенную область. Появится одно окно с фото, брендом и артикулом. Нажмите «ОК», затем «Скопировать ссылку». Несколько файлов получают общие бренд и артикул. Пока «ОК» не нажато, фото остаются приватными.
Все методы доступны также на https://fiqo.ru/api/v1/media/…. Интерфейс использует собственную сессию на /api/media-library/…; постоянный ключ в браузер не передаётся. Закрытая ссылка возвращает 403/404, устаревший предпросмотр — 404/410, неверный формат — 415, превышение квоты/размера — 413, временная ошибка хранилища или таймаут — 502/503/504.
Пакетный импорт и источники · 014
Базовый адрес https://media.fiqo.ru/v1. Серверный ключ с активной подпиской медиа: media:write для загрузки и управления, media:read для чтения. Все задания и предпросмотры изолированы по кабинету.
POST /batches/preview: тело — файл XLSX/CSV,Content-Type: application/octet-stream,X-Filename: images.xlsx(имя кодируется encodeURIComponent). До 5 МБ, 5000 строк. Ответ:id,headers,mapping,rows,total,sheet. Предпросмотр действует 30 минут.POST /batches/validateс JSON{"previewId":"ID","mapping":{"url":0,"brand":1,"article":2}}. Номера колонок начинаются с нуля. Ответ: первые 100 проверенных строк, total, invalid, duplicates. До создания задания можно исправить сопоставление.GET /sources— собственные источники;POST /sourcesс{"name":"Каталог поставщика"}создаёт именованный источник кабинета. Повторное название возвращает существующий источник. До 100 источников.POST /batchesс{"previewId":"ID","mapping":{"url":0,"brand":1,"article":2},"sourceId":"SOURCE_ID"}создаёт устойчивую очередь. sourceId можно опустить — используются «Загрузки клиента». Ответ содержит id задания. До 3 незавершённых заданий на кабинет.GET /batches— последние 100 заданий.GET /batches/{id}?cursor=0— результаты и курсор изменений:rows,changeCursor,hasMore,counts,state. При hasMore продолжайте с changeCursor; затем сохраняйте строки по ключу line вместе с курсором и запрашивайте только изменения. Одна строка может прийти повторно с новым состоянием. Обычная пагинация снимка также доступна через after и nextCursor.POST /batches/{id}:{"action":"pause"}либо{"action":"retry"}. retry повторяет ошибки скачивания и продолжает приостановленное задание. Строки invalid требуют исправления исходной таблицы.
Статусы строки: queued, running, stored, duplicate, duplicate-row, invalid, error. Статусы задания: queued, running, paused, done. done означает завершение обработки, а не отсутствие ошибок — проверяйте counts и error у строк. Результат строки содержит image_url и image. Фотографии привязаны к бренду и артикулу и сохранены локально; ссылки Диска не используются как постоянные URL.
Все новые изображения общего каталога проходят модерацию. Личный опубликованный набор доступен его клиенту сразу; общий lookup выдаёт только approved от активного источника. Блокировка источника действует без переписывания всех изображений. Одинаковый файл хранится один раз; происхождение сохраняется отдельно. Методы /admin/* дополнительно требуют администратора; они недоступны обычному клиенту и пользовательскому встраиванию.
Хранилище: 200 МБ на кабинет, 10 МБ на фотографию. При нехватке места на физическом диске — HTTP 507; блокировка источника — 403; чужое задание — 404; просроченный предпросмотр — 410. Формулы XLSX, папки Диска и закрытые файлы не поддерживаются. Несколько фото одного товара добавляются по порядку; существующее основное сохраняется.