Тема
POST /v1/inbound/leads
Принять новый лид от партнёра.
Запрос
http
POST /v1/inbound/leads HTTP/1.1
Host: cartelcrm.com
Authorization: Bearer <api_key>
X-Signature: sha256=<HMAC-SHA256(body, hmac_secret)>
X-Timestamp: <unix seconds>
Idempotency-Key: <ваш-уникальный-id>
Content-Type: application/jsonBody
Минимально-достаточный набор (если ваш партнёр не использует кастомный field_mapping):
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
external_id | string | нет* | Ваш id лида. Если не передан — будет использован Idempotency-Key. |
first_name | string | нет | Имя. |
last_name | string | нет | Фамилия. |
full_name | string | нет | Если не передан — соберём из first_name + last_name. |
email | string | нет | Email (хранится зашифрованно + хэш для поиска). |
phone | string | да | Телефон в международном формате с +. Шифруется + хэшируется. |
country | string | нет | Страна. 2-буквенный ISO предпочтителен. |
country_code | string | нет | Если не передан — выведем из country. |
language | string | нет | ISO-код языка (en, ru, es...). |
ip | string | нет | IP клиента. Если не передан — возьмём IP запроса. |
user_agent | string | нет | UA клиента. |
source | string | нет | Источник трафика (facebook_ads, google, email, ...). |
funnel | string | нет | Какая воронка лила. |
sub_id | string | нет | Ваш sub-id для пост-бэк трекинга. |
click_id | string | нет | Ваш click-id. |
landing_url | string | нет | URL посадки, где заполнялась форма. |
metadata | object | нет | Любые ваши дополнительные поля. |
* Хотя external_id формально опционален, очень советуем передавать — иначе у вас не будет стабильного ключа для последующего GET /v1/inbound/leads/{externalId}/status.
Вложенный payload
Если вы шлёте в своём формате (profile.firstName, contact.phone, и т.д.) — это нормально. Менеджер настроит Field mapping под ваш payload, без изменений на вашей стороне.
Пример тела
json
{
"external_id": "aff42-lead-001",
"first_name": "Иван",
"last_name": "Петров",
"phone": "+380501234567",
"email": "ivan@example.com",
"country": "UA",
"language": "ru",
"source": "facebook_ads",
"funnel": "crypto-v3",
"sub_id": "sub-789",
"click_id": "fb-click-abc",
"landing_url": "https://landing.example/cr/v3?utm=fb"
}Ответы
200 OK — лид принят
json
{
"id": "le-12345",
"status": "accepted",
"reason": null,
"duration_ms": 42
}id— наш internal id, его удобно сохранить у себя для дебага.duration_ms— сколько у нас занял весь intake (валидация → дедуп → сохранение → распределение).
После 200 — ждите callback lead.accepted, а потом — события смены статуса.
409 Conflict — duplicate
json
{
"id": "le-12340",
"status": "duplicate",
"reason": "matched_lead:12340"
}Найден лид в окне дедупликации (default 30 дней) с совпавшим phone или email. id — это id существующего лида (не нового). Никаких изменений в базе не произошло.
422 Unprocessable Entity — валидация / бизнес-правила
json
{
"id": null,
"status": "validation_error",
"reason": "missing_required:phone"
}или
json
{
"id": null,
"status": "rejected",
"reason": "country_blocked:US"
}См. Коды ошибок для полного списка reason.
200 OK с replay: true — идемпотентный повтор
json
{
"id": "le-12345",
"status": "accepted",
"reason": null,
"replay": true
}Если вы повторили запрос с тем же Idempotency-Key (в окне 24 часов), мы вернули сохранённый результат без обработки. См. Idempotency.
401 Unauthorized / 403 Forbidden
См. Authentication и Коды ошибок.
429 Too Many Requests
json
{
"error": "rate_limit_exceeded",
"message": "Try again in 18 seconds"
}Заголовок Retry-After содержит время до разблокировки. См. Rate limits.
Полный cURL-пример
bash
BODY='{"external_id":"aff42-lead-001","phone":"+380501234567","source":"facebook_ads","country":"UA"}'
TS=$(date +%s)
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex | awk '{print $2}')
curl -X POST https://cartelcrm.com/api/v1/inbound/leads \
-H "Authorization: Bearer $API_KEY" \
-H "X-Signature: sha256=$SIG" \
-H "X-Timestamp: $TS" \
-H "Idempotency-Key: aff42-lead-001-r0" \
-H "Content-Type: application/json" \
-d "$BODY"См. также: Примеры на Node/PHP/Python.