GOODVIN
+7 958 111-05-06Демо

Описание REST API

Пятнадцать методов, которые проводят покупателя от VIN до оригинального артикула. Обычный JSON поверх HTTPS: без SDK, без обязательных библиотек, без собственного формата ответа.

Открыть консоль
GET /car/info
# Машина по VIN — один запрос
curl -sG https://api.goodvin.net/v1/car/info \
-H "Authorization: $KEY" \
--data-urlencode "q=XW8AN2NE3JH035743"
# В ответе то, чем пользуются все
# остальные методы:
catalogId "vw"
carId "vw-polo-2018-cfna"
criteria "AAAAAB;2018;CFNA;RUS"
Основа

Адрес, ключ и язык

Три вещи, которых хватает для первого запроса.

https://api.goodvin.net/v1адрес
Общее начало всех адресов. Спецификация OpenAPI 3.0 лежит по этому же адресу: её можно скормить Postman, Insomnia или генератору клиента и не переписывать методы руками.
Authorization: ваш ключзаголовок
Ключ передаётся голым значением. Слова Bearer перед ним быть не должно: с ним запрос вернёт 401.
Accept-Language: ruнеобязательно
Язык названий узлов и деталей. Доступны: ru, en, de, fr, es, bg, he. По умолчанию английский, поэтому для русского магазина заголовок стоит слать всегда.
GETединственный метод
Все вызовы — обычные GET с параметрами в строке запроса. Тела запроса нет ни у одного метода.
Сценарий

Путь от номера до артикула

Каталог устроен деревом, и методы вызываются не вразнобой, а цепочкой: ответ предыдущего кормит следующий.

  1. 1
    Проверяем номер

    Валидатор чинит частые опечатки (O вместо нуля, I вместо единицы) и объясняет, что именно поправил. Дешевле, чем показать покупателю пустую выдачу.

    GET /cars/vin-validator
  2. 2
    Определяем машину

    VIN или номер кузова: тип определяется сам. В ответе приходят catalogId, carId и criteria. Эта тройка нужна дальше везде.

    GET /car/info
  3. 3
    Спускаемся по дереву узлов

    Первый вызов без groupId отдаёт верхний уровень. Дальше подставляем идентификатор выбранного узла и повторяем, пока в ответе не появится hasParts: true.

    GET /catalogs/{catalogId}/groups2/
  4. 4
    Забираем детали

    Схема узла, оригинальные артикулы, применимость и координаты выносок на картинке — всё одним ответом. Остаётся сопоставить артикулы со своим складом.

    GET /catalogs/{catalogId}/parts2

Если номера нет, начало другое: /catalogs/ → /models/ → /cars-parameters/ → /cars2/. Дальше с третьего шага, дерево и детали те же.

Быстрый старт

Тот же путь на четырёх языках

Скопируйте, подставьте ключ в переменную окружения — и первый ответ придёт раньше, чем вы дочитаете справочник.

# Ключ передаётся голым значением, без слова Bearer
export KEY="ваш ключ"
# 1. Правим опечатки в номере до того, как тратить запрос
curl -sG https://api.goodvin.net/v1/cars/vin-validator \
-H "Authorization: $KEY" \
--data-urlencode "vin=XW8AN2NE3JH035743"
# 2. Определяем машину. В ответе catalogId, carId и criteria
curl -sG https://api.goodvin.net/v1/car/info \
-H "Authorization: $KEY" \
-H "Accept-Language: ru" \
--data-urlencode "q=XW8AN2NE3JH035743"
# 3. Верхний уровень узлов найденной машины
curl -sG https://api.goodvin.net/v1/catalogs/vw/groups2/ \
-H "Authorization: $KEY" \
--data-urlencode "carId=$CAR_ID" \
--data-urlencode "criteria=$CRITERIA"
# 4. Детали узла, у которого пришло hasParts: true
curl -sG https://api.goodvin.net/v1/catalogs/vw/parts2 \
-H "Authorization: $KEY" \
--data-urlencode "carId=$CAR_ID" \
--data-urlencode "groupId=$GROUP_ID" \
--data-urlencode "criteria=$CRITERIA"
Ключ не должен попасть в браузер

Заголовок Access-Control-Allow-Origin у нас открыт, так что дёрнуть API прямо из скрипта на странице технически можно. Так делать нельзя. Ключ в исходниках виден каждому посетителю и уедет вместе с первым любопытным, а привязки к домену, которая страхует виджет, здесь нет. Запрос уходит с вашего сервера, наружу отдаётся готовый результат.

Ответ

Что приходит на второй строке

Разбор ответа car/info: остальные методы устроены так же — плоский JSON без обёрток вроде data или result.

200 OK
[
{
"title": "VOLKSWAGEN POLO 1.6 MPI",
"catalogId": "vw",
"brand": "Volkswagen",
"modelId": "5bb58a3cab059a189ef92be181380fd5",
"carId": "vw-polo-2018-cfna",
"criteria": "AAAAAB;2018;CFNA;RUS",
"vin": "XW8AN2NE3JH035743",
"modelName": "Polo (612)",
"groupsTreeAvailable": true,
"optionCodes": [
{ "code": "0GC", "description": "Кондиционер" }
],
"parameters": [
{ "key": "year", "name": "Год выпуска", "value": "2018", "sortOrder": 1 }
]
}
]
carId
Идентификатор машины внутри каталога. Не вечный: при обновлении баз он меняется. В своей базе храните VIN, а carId считайте временным — как номер сессии.
criteria
Слепок комплектации. Его нужно передавать в каждый следующий запрос, иначе выдача не сузится до конкретной машины и покупатель увидит детали от чужой модификации.
catalogId
Каталог, в котором машина нашлась. Подставляется в адрес всех методов по узлам и деталям.
groupsTreeAvailable
Показывает, доступен ли для этой машины метод groups-tree. Если false — идите обычным спуском по groups2.
optionCodes
Заводские коды опций с расшифровкой. Пригодятся, когда покупатель спорит, была ли у него на машине эта комплектация.
Справочник

Пятнадцать методов

Версия 1.18.0. Машинную спецификацию OpenAPI сервер отдаёт по тому же адресу, что и данные, и она всегда свежее любой страницы.

Можно не читать, а попробовать

Любой метод из списка вызывается прямо в браузере: вставьте ключ и нажмите Execute. Без ключа сразу работают два метода — этого хватает, чтобы увидеть формат ответа.

Открыть консоль

Служебное

С чего начать, когда ключ только пришёл и непонятно, доходят ли запросы вообще.

GET/ip/без ключа

Адрес, с которого вы стучитесь

Единственный метод, который отвечает без ключа. Полезен, когда запросы идут через прокси или балансировщик и надо понять, какой адрес сервер видит на самом деле.

{ "ip": "203.0.113.10" }

GET/catalogs/

Каталоги, открытые вашему ключу

Список марок с числом моделей и датой актуальности. У каждого каталога четыре флага: hasVinCheck и hasFrameCheck говорят, ищет ли марка по номеру, hasGroupTree и hasUniTree — какие деревья узлов доступны. По ним видно, что предлагать покупателю, ещё до первого поиска.

Параметры
Accept-LanguageзаголовокЯзык названий

Массив Catalog: id, name, modelsCount, actuality, флаги

Автомобиль

Два пути к машине: по номеру, когда покупатель его знает, и перебором по модели, когда нет.

GET/cars/vin-validator

Проверка VIN на опечатки

Разбирает введённый номер по общим правилам и возвращает исправленный вариант вместе со списком правок: какие символы заменены и почему. Ставьте перед поиском: так опечатка покупателя не превратится в пустую выдачу.

Параметры
vin •запросНомер как его ввёл покупатель
Accept-LanguageзаголовокЯзык текста ошибок

CarValidate: original, changed, errors[] с расшифровкой

GET/car/info

Определение машины по VIN или номеру кузова

Главный метод подбора. Тип номера определяется сам, различать VIN и FRAME на своей стороне не нужно. В ответе приходит связка catalogId + carId + criteria. Дальше все запросы идут с ней.

Параметры
q •запросVIN или номер кузова
catalogsзапросСузить поиск списком каталогов через запятую: kia,bmw,hyundai
Accept-LanguageзаголовокЯзык ответа

Массив CarInfo: title, brand, catalogId, carId, criteria, optionCodes, parameters

GET/catalogs/{catalogId}/models/

Модели каталога

Начало подбора без номера: список моделей марки с картинками.

Параметры
catalogId •путьИдентификатор каталога
Accept-LanguageзаголовокЯзык названий

Массив Model: id, name, img

GET/catalogs/{catalogId}/cars-parameters/

Фильтры модели

Кузов, годы, двигатель, рынок — то, из чего собирается форма подбора. В заголовке X-Cars-Count приходит число машин, оставшихся после выбранных фильтров: можно показывать счётчик, не запрашивая сам список.

Параметры
catalogId •путьИдентификатор каталога
modelId •запросИдентификатор модели
parameterзапросУже выбранные значения фильтров (idx через запятую)

Массив CarParameterInfo. Поле sortOrder задаёт порядок полей в форме: чем меньше, тем выше

GET/catalogs/{catalogId}/cars2/

Машины модели

Список комплектаций, отфильтрованный параметрами. По 25 записей на страницу, общее число — в заголовке X-Total-Count.

Параметры
catalogId •путьИдентификатор каталога
modelId •запросИдентификатор модели
parameterзапросЗначения фильтров (idx)
pageзапросНомер страницы, больше нуля

Массив Car2 + заголовок X-Total-Count

GET/catalogs/{catalogId}/cars2/{carId}

Одна машина по идентификатору

Понадобится, когда покупатель вернулся по сохранённой ссылке, а разбирать её заново не хочется.

Параметры
catalogId •путьИдентификатор каталога
carId •путьИдентификатор машины
criteriaзапросСтрока комплектации из car/info

Car2: name, brand, modelName, vin, frame, criteria, parameters

Узлы

Каталог устроен деревом. Спускаться по нему нужно до листа — там лежат детали.

GET/catalogs/{catalogId}/groups2/

Узлы автомобиля

Без groupId отдаёт верхний уровень. Дальше подставляйте идентификатор выбранного узла и спускайтесь, пока hasParts не станет true — это и есть признак, что внутри лежат артикулы, а не следующий уровень.

Параметры
catalogId •путьИдентификатор каталога
carId •запросИдентификатор машины
groupIdзапросУзел, внутрь которого спускаемся. Пусто — верхний уровень
criteriaзапросСтрока комплектации из car/info

Массив Group: id, name, img, hasSubgroups, hasParts

GET/catalogs/{catalogId}/groups-suggest

Подсказка по названию детали

Покупатель пишет «аморт» — метод предлагает узлы, где встречается амортизатор. Возвращает sid, по которому можно достать сами узлы.

Параметры
catalogId •путьИдентификатор каталога
q •запросПервые буквы названия

Массив Suggest: sid, name

GET/catalogs/{catalogId}/groups-tree

Всё дерево одним запросом

Когда нужна вся структура сразу, например для своей навигации по каталогу. Флаг cached=true отдаёт общее дерево из кеша и отвечает быстро; cached=false собирает дерево под конкретную машину, но заметно дольше.

Параметры
catalogId •путьИдентификатор каталога
carIdзапросИдентификатор машины
criteriaзапросСтрока комплектации
cachedзапросtrue — общее дерево из кеша, false — отфильтрованное

Дерево GroupsTreeResponse с вложенными subGroups

GET/catalogs/{catalogId}/schemas

Схемы узлов

Схемы, каждая из которых ведёт сразу на страницу деталей, минуя спуск по дереву. Можно отфильтровать по ветке или по названию детали. По 24 схемы на страницу.

Параметры
catalogId •путьИдентификатор каталога
carId •запросИдентификатор машины
branchIdзапросОграничить ветвью дерева
partNameзапросОтобрать по названию детали
partNameIdsзапросТо же, но по идентификаторам: 56,85
pageзапросСтраница, по 24 элемента

SchemasResponse: group + list[] со схемами и названиями деталей

GET/catalogs/{catalogId}/groups-by-sidустарел

Узлы по идентификатору подсказки

Помечен устаревшим на стороне сервера. В новых интеграциях не используйте: сузить выдачу лучше через schemas с параметром partName.

Параметры
catalogId •путьИдентификатор каталога
sid •запросИдентификатор из groups-suggest
carId •запросИдентификатор машины

Массив Group

Детали

Конец пути: артикулы, схема узла и координаты выносок на ней.

GET/catalogs/{catalogId}/parts2

Детали узла

Отдаёт разом всё, из чего собирается страница узла: картинку схемы, список деталей с оригинальными артикулами и координаты выносок на схеме, чтобы номер на картинке можно было связать со строкой в списке.

Параметры
catalogId •путьИдентификатор каталога
carId •запросИдентификатор машины
groupId •запросУзел, у которого hasParts: true
criteriaзапросСтрока комплектации
x-redirect-templateзаголовокШаблон ваших адресов для ссылок внутри описаний

Parts: img, partGroups[] с деталями, positions[] с координатами выносок

GET/example/pricesбез ключа

Цены и наличие — образец

Показывает, как может выглядеть ответ с ценой, остатком и сроком поставки. Данные в нём выдуманные и не меняются: метод существует, чтобы проектировщик интеграции увидел форму ответа. Свои цены вы подставляете из учётной системы.

Параметры
code •запросАртикул
brand •запросБренд

Массив ExamplePricesResponse: price, inStockQty, delivery, rating

— обязательный параметр. Всем методам, кроме помеченных «без ключа», нужен заголовок авторизации.

Заголовки ответа

Три, которые пригодятся

Часть данных приходит не в теле, а в заголовках. Их легко не заметить и потом собирать пагинацию наугад.

X-Total-Count
Сколько всего записей — для пагинации в cars2 и schemas
X-Cars-Count
Сколько машин осталось после фильтров в cars-parameters
x-request-id
Идентификатор запроса. Приложите его к обращению в поддержку: по нему найдут ваш случай в логах
Опыт

На чём спотыкаются в первую неделю

Ничего из этого не считается ошибкой на стороне сервера: он честно отвечает на то, о чём его спросили.

Потерянная criteria
Самая дорогая из ошибок: без неё дерево показывает узлы всей модели. Покупатель закажет деталь от чужой комплектации, а вернёт её вам.
parts2 у промежуточного узла
Метод отвечает 404, пока у узла hasParts: false. Это не сбой — просто внутри лежат подузлы, а не артикулы. Проверяйте флаг перед вызовом.
Грузовые каталоги
Для грузовиков работают только groups2 и parts2 — версии методов с двойкой. Старые ветки по ним молчат.
Ссылки внутри описаний
В примечаниях к деталям встречаются переходы на другие узлы. Передайте заголовок x-redirect-template со своим форматом адресов — сервер подставит ваши ссылки вместо пустых.
Пагинация
cars2 отдаёт по 25 записей, schemas — по 24. Сколько всего, смотрите в X-Total-Count, а не по признаку «пришло меньше, чем просили».
Кеш на своей стороне
Дерево узлов и схемы у машины не меняются сутками. Сложите ответ в свой кеш и держите carId в сессии покупателя: возврат из корзины не должен стоить второго запроса.
Ошибки

Коды и что с ними делать

КодЧто означаетЧто делать
401Ключ не передан или недействителенПроверьте заголовок Authorization. Значение передаётся голым, без слова Bearer
403Ключ есть, но доступ к ресурсу закрытОбычно это каталог вне вашей подписки или домен вне списка. Напишите менеджеру
404Ничего не нашлось по этим параметрамДля parts2 чаще всего означает, что у узла hasParts: false — спуститесь глубже
400Запрос собран неверноНе хватает обязательного параметра или он не того типа
422Параметр отсутствуетВозвращает cars-parameters, когда не передан modelId
429Слишком частоПовторите через интервал из заголовка Retry-After

Тело ошибки одинаковое у всех методов: code, errorCode и message. Отдельного формата для каждого случая нет.

Когда пишете в поддержку

В каждом ответе есть заголовок x-request-id. Приложите его к письму — по нему поднимут ровно ваш запрос вместо того, чтобы просить повторить проблему и ждать, пока она воспроизведётся.

Лимиты

Песочница и боевой ключ

Запрос расходуется только на определение новой машины. Всё, что происходит внутри уже найденной, — дерево, схемы, детали — не тарифицируется.

ПараметрПесочницаБоевой ключ
Запросов в сутки100по тарифу
Частота2 запроса в секунду10 запросов в секунду
Данныеполные, тестовый набор марокполные
Срок3 днясрок подписки
Действие запроса24 часа24 часа

Повторное обращение к тому же автомобилю в течение суток отдаётся из кеша и пакет не расходует.

Европейские, японские, американские и корейские каталоги по API стоят столько же, сколько виджет: 7 590 ₽ за 1 000 запросов, 21 590 ₽ за 3 000, 33 990 ₽ за 5 000. Наценки за программный доступ нет. Китайские марки тарифицируются отдельно — 31 590 ₽ за 1 000 запросов в месяц. Объёмы от 10 000 и корпоративные условия — на отдельной странице.

То, что спрашивает техотдел

Есть ли SDK или готовая библиотека?

Обязательной библиотеки нет: это обычный REST с JSON, любой HTTP-клиент подойдёт. Спецификацию OpenAPI сервер отдаёт по адресу api.goodvin.net/v1, так что клиент для своего языка можно сгенерировать за минуту или загрузить её в Postman и Insomnia. Готовые примеры на cURL, PHP, JavaScript и Python — выше на этой странице, а вызвать метод, ничего не устанавливая, можно в консоли.

Чем API отличается от виджета?

Виджет — готовый интерфейс, который отрисовывается скриптом и в поисковый индекс не попадает. По API вы получаете данные и рисуете страницы сами, поэтому они индексируются как обычные страницы магазина. Это и есть главная причина, по которой к API переходят.

Как API влияет на скорость сайта?

Запросы идут с вашего сервера, на клиенте не грузится ничего лишнего. В отличие от виджета со своим бандлом, здесь вы контролируете каждый килобайт и можете отдавать страницу уже с деталями, из своего кеша.

Что будет, если API не ответит?

Придёт стандартный код ошибки. Показывайте покупателю форму «подберём вручную» вместо пустого экрана: заявка сохранится, даже если подбор в этот момент недоступен.

Можно тестировать без договора?

Да. Ключ для песочницы приходит на почту после заявки, привязка к домену для него не нужна. Три дня и сто запросов в сутки — этого хватает, чтобы собрать прототип подбора.

Метод /ip/ работает без ключа. Это нормально?

Да, он для того и сделан: показывает, с какого адреса сервер видит ваши запросы. Полезно, когда трафик идёт через прокси или балансировщик и надо понять, какой адрес добавлять в списки. Данных каталога он не отдаёт.

Возьмите ключ и попробуйте

Приходит на почту вместе со ссылкой на документацию. Домен указывать не нужно.

+7 958 111-05-06