← Convioo

Документация для разработчиков

Публичное REST API Convioo — аутентификация, вебхуки, события и схемы payload. Интерактивный справочник на https://api.convioo.com/docs.

Аутентификация

Каждый запрос к API требует API-ключ. Создайте его в разделе Настройки → API-ключи, затем передавайте его в заголовке: Authorization: Bearer.

Работают и сессионные cookie (в браузере), и токены Bearer. Если присутствуют оба, приоритет у токена Bearer.

curl https://api.convioo.com/api/v1/searches \
  -H "Authorization: Bearer convioo_pk_<your-key>"
API-ключи начинаются с префикса convioo_pk_. Они показываются только один раз при создании — сразу сохраните их в менеджере секретов.

Базовый URL

https://api.convioo.com

Все пути в этом документе указаны относительно этого базового адреса. Запросы из веб-приложения Convioo проходят через прокси-перезапись Next.js /api/* — внешние скрипты должны всегда обращаться напрямую к URL на Railway.

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

1. Получите свои поиски

curl https://api.convioo.com/api/v1/searches \
  -H "Authorization: Bearer convioo_pk_<key>"

# → { "items": [...], "total": 12 }

2. Получите лиды по поиску

curl "https://api.convioo.com/api/v1/searches/<search_id>/leads?limit=20" \
  -H "Authorization: Bearer convioo_pk_<key>"

3. Обновите статус лида

curl -X PATCH "https://api.convioo.com/api/v1/leads/<lead_id>" \
  -H "Authorization: Bearer convioo_pk_<key>" \
  -H "Content-Type: application/json" \
  -d '{"lead_status": "contacted"}'

4. Экспортируйте лиды в Notion

curl -X POST "https://api.convioo.com/api/v1/leads/export-to-notion" \
  -H "Authorization: Bearer convioo_pk_<key>" \
  -H "Content-Type: application/json" \
  -d '{"lead_ids": ["<uuid1>", "<uuid2>"]}'

Вебхуки

Convioo отправляет подписанный запрос POST на ваш URL, когда срабатывает подписанное событие. Настройте вебхуки в разделе Настройки → Вебхуки.

Заголовки запроса

ЗаголовокЗначение
X-Convioo-Signaturesha256=<HMAC-SHA256 hex digest> (legacy, kept for compatibility)
X-Convioo-Timestamp<unix seconds> — when the delivery was signed
X-Convioo-Signature-Timestampedt=<ts>,v1=<HMAC-SHA256 of "<ts>.<body>">
X-Convioo-Eventlead.created | lead.status_changed | search.finished | webhook.test
X-Convioo-Deliveryunique delivery UUID
Content-Typeapplication/json
User-AgentConvioo-Webhooks/1.0

Структура payload

{
  "event": "lead.created",
  "delivery_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "delivered_at": "2026-05-03T14:22:00Z",
  "data": { ... }
}

Проверка подписи

Вычислите HMAC-SHA256(secret, raw_body) и сравните результат с hex-дайджестом в X-Convioo-Signature (после префикса sha256= ). Используйте сравнение за постоянное время, чтобы защититься от атак по времени.

python
# Python
import hashlib, hmac

def verify(secret: str, body: bytes, header: str) -> bool:
    expected = "sha256=" + hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, header)
javascript
// Node.js
const crypto = require("crypto");

function verify(secret, body, header) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(body)          // Buffer or string
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(header),
  );
}

Защита от повторов (подпись с меткой времени)

Каждая доставка также несёт подпись с меткой времени. Старый заголовок выше остаётся без изменений для обратной совместимости, но рекомендуем проверять именно эту подпись: она позволяет отклонять повторно отправленные доставки. Вычислите HMAC-SHA256(secret, "<timestamp>.<raw_body>"), сравните в постоянном времени со значением v1 и отклоните запрос, если метка времени отличается от ваших часов более чем на 5 минут.

python
# Python — timestamped (replay-safe) verification
import hashlib, hmac, time

def verify_timestamped(secret: str, body: bytes, ts: str, header: str) -> bool:
    # header looks like: t=<ts>,v1=<hex>
    parts = dict(p.split("=", 1) for p in header.split(","))
    if abs(time.time() - int(ts)) > 300:  # 5-minute tolerance
        return False
    expected = hmac.new(
        secret.encode(), f"{ts}.".encode() + body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Политика повторов и сбоев

Convioo считает успехом любой ответ 2xx Если ваш эндпоинт пять раз подряд возвращает статус не из диапазона 2xx или превышает таймаут (5 с), вебхук автоматически отключается. Включите его заново в Настройках; счётчик сбоев сбрасывается при следующей успешной доставке.

События & схемы payload

lead.created

Срабатывает, когда новый лид попадает в CRM (в конце прогона поискового пайплайна).

{
  "event": "lead.created",
  "data": {
    "id": "<uuid>",
    "name": "Acme Roofing",
    "score": 82,
    "lead_status": "new",
    "phone": "+1-555-0100",
    "website": "https://acmeroofing.com",
    "address": "123 Main St, New York, NY",
    "category": "Roofing",
    "rating": 4.6,
    "reviews": 47,
    "source": "google",
    "created_at": "2026-05-03T14:22:00Z"
  }
}

lead.status_changed

Срабатывает, когда у лида обновляется lead_status (через PATCH-эндпоинт лида или массовое действие в CRM).

{
  "event": "lead.status_changed",
  "data": {
    "id": "<uuid>",
    "name": "Acme Roofing",
    "lead_status": "contacted",
    "previous_status": "new",
    "changed_at": "2026-05-03T15:00:00Z"
  }
}

search.finished

Срабатывает, когда поисковый пайплайн завершается (успешно или с ошибкой).

{
  "event": "search.finished",
  "data": {
    "search_id": "<uuid>",
    "niche": "Roofing companies",
    "region": "New York",
    "leads_found": 23,
    "status": "completed",
    "finished_at": "2026-05-03T14:25:00Z"
  }
}

webhook.test

Срабатывает, когда вы нажимаете Тест в Настройках. Используйте, чтобы проверить, что ваш эндпоинт доступен и подписи проходят валидацию.

{
  "event": "webhook.test",
  "data": {
    "webhook_id": "<uuid>",
    "message": "This is a test delivery from Convioo."
  }
}

Лимиты запросов

Группа эндпоинтовЛимит
POST /api/v1/searches20 req / 10 min per user
POST /api/v1/assistant/chat60 req / 10 min per user
Все остальные эндпоинты300 req / min per key

При превышении лимита возвращается 429 Too Many Requests с заголовком Retry-After (в секундах).

Формат ошибок

{
  "detail": "human-readable error message"
}
СтатусЗначение
400Некорректное тело запроса или нарушение бизнес-правила
401Отсутствующие или недействительные учётные данные
403Учётные данные верны, но прав недостаточно
404Ресурс не найден
422Ошибка валидации Pydantic (некорректный JSON)
429Превышен лимит запросов
503Функция не настроена на этом развёртывании

Интерактивный справочник

Полная спецификация OpenAPI (автоматически генерируется FastAPI) доступна по адресам:

https://api.convioo.com/docs       # Swagger UI
https://api.convioo.com/redoc      # ReDoc
https://api.convioo.com/openapi.json   # raw JSON

Спецификация всегда соответствует работающему бэкенду — она описывает схему каждого запроса и ответа и указывает, какие эндпоинты требуют аутентификации.