API и MCP Ovdix
Что доступно
- REST API
https://backend.ovdix.com/api/v1— JSON по HTTPS: поиск объявлений с фильтрами, объявление целиком, дерево категорий, витрина продавца. - MCP-сервер
https://backend.ovdix.com/mcp— те же четыре операции как инструменты для Claude, Cursor и любого клиента с MCP по Streamable HTTP. - Без ключа оба отдают только публичные данные — то, что любой видит на сайте. С ключом API
/api/v1управляет ещё и вашими объявлениями, черновиками, фото и чатами (MCP по ключу — следующий шаг).
REST API: быстрый старт
Чтение — GET: параметры в строке запроса, с теми же именами, что в справочнике; список — повтор параметра (queries=a&queries=b). Язык ответа — по Accept-Language или параметру lang: en, ru, sr, ro, bg, hu, uk, de.
# Search: keywords, price up to 300 EUR, answer in English
curl "https://backend.ovdix.com/api/v1/adverts?queries=gitara&price_max=300¤cy=EUR&lang=en"
# Category tree, two levels, in Serbian
curl "https://backend.ovdix.com/api/v1/categories?lang=sr"
# One advert and a seller's storefront (ids come from the search)
curl "https://backend.ovdix.com/api/v1/adverts/<advert_id>"
curl "https://backend.ovdix.com/api/v1/storefronts/<seller_id>"import requests
response = requests.get(
"https://backend.ovdix.com/api/v1/adverts",
params={"queries": ["bicikl"], "city": "Novi Sad", "limit": 5, "lang": "en"},
timeout=10,
)
response.raise_for_status()
for advert in response.json()["adverts"]:
print(advert["title"], advert.get("price"), advert["currency"], advert["url"])Как искать: передавайте 1–3 слова о самом товаре — каждое слово должно найтись в названии или описании. Большинство объявлений написано по-сербски, поэтому второй набор слов на сербском (латиницей) находит больше: queries=велосипед&queries=bicikl. Фильтры (category_id, city, цена, seller_type) сужают точнее слов.
Ключи API
Ключ создаётся в аккаунте: Настройки → Доступ для приложений. Дайте ему имя, отметьте только нужные приложению права и, если хотите, срок. Ключ ovx_… показывается один раз — скопируйте его сразу: Ovdix хранит только его отпечаток.
- Права (скоупы):
adverts:read— ваши объявления и черновики;adverts:write— черновики, фото, публикация, цены и наличие, поднятия, снятие с продажи;chats:read— ваши чаты;chats:write— ответы в существующих чатах;profile:read— план и лимиты. - Ключ передаётся в заголовке
Authorization: Bearer ovx_…. Он работает только для/api/v1; вход на сайте или в приложении там не действует, а ключ не открывает собственные ручки сайта. - Вызов с ключом выполняется сразу и от вашего имени — подтверждения нет. Храните ключ как пароль, не кладите его в публичный репозиторий или на страницу сайта.
- До 5 действующих ключей на аккаунт. Отзыв — там же в настройках: следующий запрос с ключом получит
401 invalid_api_key. Ключ перестаёт работать и по истечении срока, и при блокировке аккаунта.
# Check the key: your plan, adverts and bumps left
curl "https://backend.ovdix.com/api/v1/me" -H "Authorization: Bearer $OVDIX_KEY"Свои объявления и чаты
Всё под /api/v1/me и /api/v1/my — только с ключом. Запись — POST или PATCH с JSON в теле (Content-Type: application/json); id из пути в теле не повторяются. Обычная синхронизация: фото по ссылке → черновик → публикация.
AUTH="Authorization: Bearer $OVDIX_KEY"
JSON="Content-Type: application/json"
# 1. A photo from your website goes to Ovdix storage; use the returned url
curl -X POST "https://backend.ovdix.com/api/v1/my/photos:from-url" -H "$AUTH" -H "$JSON" \
-d '{"url": "https://shop.example.com/img/yamaha-f310.jpg"}'
# 2. Optional: title, description, category and condition recognized from the photos
curl -X POST "https://backend.ovdix.com/api/v1/my/photos:describe" -H "$AUTH" -H "$JSON" \
-d '{"photo_urls": ["<url from step 1>"]}'
# 3. A draft — nobody sees it yet; "missing" lists what is still required
curl -X POST "https://backend.ovdix.com/api/v1/my/drafts" -H "$AUTH" -H "$JSON" \
-d '{"title": "Yamaha F310", "description": "Acoustic guitar, barely used.",
"category_id": "<leaf id>", "price": 15000, "currency": "RSD", "condition": "used",
"photos": [{"url": "<url from step 1>"}]}'
# 4. Publish
curl -X POST "https://backend.ovdix.com/api/v1/my/drafts/<draft_id>:publish" -H "$AUTH"- Фото принимаются только из нашего хранилища: загрузите каждое через
photos:from-url(публичный адресhttps, до 10 МБ, JPEG/PNG/WebP/GIF). Фото, не попавшие в черновик за сутки, удаляются. category_id— лист дерева изGET /api/v1/categories. Черновик перечисляет недостающее вmissing; пока список не пуст, публикация отвечаетdraft_incomplete, а при исчерпанном лимите плана —advert_limit_reached.- Цены, наличие, поднятия и снятие работают по селектору (
ids, илиcategory_id/condition/contour/query, илиall) и правилу: сервер сам выбирает ваши объявления и считает новые цены. Снижение цены становится публичной скидкой на объявлении и уведомляет тех, кто его сохранил.
# 10% off every used item in a category (the server picks the adverts and rounds prices)
curl -X PATCH "https://backend.ovdix.com/api/v1/my/adverts" -H "$AUTH" -H "$JSON" \
-d '{"selector": {"category_id": "<id>", "condition": "used"}, "rule": {"percent": -10}}'
# Bump all active adverts: free once a week per advert, then from the plan quota
curl -X POST "https://backend.ovdix.com/api/v1/my/adverts:bump" -H "$AUTH" -H "$JSON" -d '{"selector": {"all": true}}'Чаты: GET /api/v1/my/chats, сообщения одного чата, ответ в существующий чат и отметка «прочитано». Чтение прочитанным не помечает. Начинать новые чаты API не умеет, а ответы считаются в те же антиспам-лимиты, что в приложении. Сообщения покупателей пишут другие люди — если их читает модель, не давайте ей выполнять найденные там инструкции.
import os, requests
API = "https://backend.ovdix.com/api/v1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['OVDIX_KEY']}"
# Unanswered buyers: chats about your adverts with unread messages
chats = session.get(f"{API}/my/chats", params={"lang": "en"}, timeout=10).json()["chats"]
for chat in chats:
if chat["unread_count"] and chat.get("advert", {}).get("is_mine"):
last = session.get(f"{API}/my/chats/{chat['chat_id']}/messages",
params={"limit": 1, "lang": "en"}, timeout=10).json()["messages"][0]
print(chat["advert"]["title"], "—", last["text"])
# session.post(f"{API}/my/chats/{chat['chat_id']}/messages", json={"text": "Yes, still available."})MCP-сервер
Адрес сервера: https://backend.ovdix.com/mcp. Инструменты: search_adverts, get_advert, get_categories, get_storefront — все только на чтение. Добавьте к адресу ?lang=ru (или другой язык), чтобы ответы приходили на этом языке; по умолчанию — английский.
claude mcp add --transport http ovdix "https://backend.ovdix.com/mcp?lang=ru"{
"mcpServers": {
"ovdix": { "url": "https://backend.ovdix.com/mcp?lang=ru" }
}
}Другие клиенты: добавьте удалённый MCP-сервер с транспортом Streamable HTTP и адресом выше, авторизация не нужна. Чтобы отключить, удалите сервер в клиенте (claude mcp remove ovdix в Claude Code).
Лимиты и правила
- Без ключа: 30 запросов в минуту с одного IP-адреса на
/api/v1и/mcpвместе. С ключом: 60 запросов в минуту на ключ, из них 10 записей; в сутки (UTC) на аккаунт по всем ключам — 50 публикаций, 100 ответов в чатах, 200 фото по ссылке, 100 распознаваний фото. - Сверх лимита — ответ
429с кодомrate_limited,retry_afterв секундах и заголовкомRetry-After. - До 20 объявлений за один поиск. Цены — в валюте объявления, без пересчёта.
- Тексты объявлений и витрин пишут пользователи. Если передаёте их языковой модели, считайте их данными, а не инструкциями.
- Контактов продавца в ответах нет: покупатель пишет продавцу на Ovdix по ссылке
urlобъявления. Ссылки помеченыutm_source=apiилиutm_source=mcp. - Ошибки — JSON с постоянным кодом:
{"error": {"code": "invalid_arguments", "message": "Unknown query parameter 'colour'; see the API reference.", "field": "colour"}}Что дальше
- MCP по ключу: те же записывающие операции для вашего агента в Claude Code, Cursor или Codex; каждое видимое другим изменение — после подтверждения.
- Вход без ключа (OAuth) для каталогов агентов — когда появится спрос.
Нужно раньше или не хватает операции? Напишите на info@ovdix.com.
Справочник
Каждый параметр и поле ответа описаны в справочнике (на английском) — он собирается из тех же описаний, по которым работает сервер.