Тема
cURL примеры
Полезно для отладки руками или для shell-скриптов.
Переменные окружения
bash
export API_KEY="ccrm_live_XXXXXXXXXXXXXXXX"
export HMAC_SECRET="hmac_XXXXXXXXXXXXXXXX"
export CALLBACK_SECRET="cbk_XXXXXXXXXXXXXXXX"
export BASE_URL="https://cartelcrm.com/api"POST /v1/inbound/leads
bash
BODY='{"external_id":"aff42-lead-001","first_name":"Иван","last_name":"Петров","phone":"+380501234567","email":"ivan@example.com","country":"UA","source":"facebook_ads","funnel":"crypto-v3","sub_id":"sub-789"}'
TS=$(date +%s)
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex | awk '{print $2}')
curl -sS -X POST "$BASE_URL/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" | jq .Подпишите ту же строку, что отправляете
В bash важно: printf '%s' "$BODY" — без перевода строки. echo добавит \n и подпись не совпадёт. Если вы используете echo, то и echo "$BODY" нужно curl-у тоже передавать (но это хрупко).
GET /v1/inbound/leads/{externalId}/status
bash
EXT_ID="aff42-lead-001"
TS=$(date +%s)
# Подписываем пустое тело
SIG=$(printf '' | openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex | awk '{print $2}')
curl -sS -X GET "$BASE_URL/v1/inbound/leads/$EXT_ID/status" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Signature: sha256=$SIG" \
-H "X-Timestamp: $TS" | jq .Проверка подписи callback'а (для отладки)
Если вам прилетел callback и вы хотите вручную убедиться, что подпись валидна:
bash
# Положите тело callback'а в файл exactly as received (без переформатирования)
cat > callback-body.json <<'EOF'
{"event":"lead.ftd","external_lead_id":"aff42-lead-001","internal_id":"le-12345","status":"won","our_status":"ftd","is_depositor":true,"timestamp":"2026-05-27T14:22:03+00:00"}
EOF
# Посчитайте ожидаемую подпись
EXPECTED=$(openssl dgst -sha256 -hmac "$CALLBACK_SECRET" -hex callback-body.json | awk '{print $2}')
echo "Expected: sha256=$EXPECTED"
echo "Got: <значение из заголовка X-Signature>"
# Должны совпасть. Если нет — у вас на стороне приёма перепарсился JSON.Полезные шорткаты
Быстрый smoke-test перед боем
bash
#!/usr/bin/env bash
set -euo pipefail
: "${API_KEY:?Need API_KEY}"
: "${HMAC_SECRET:?Need HMAC_SECRET}"
: "${BASE_URL:?Need BASE_URL}"
BODY=$(printf '{"external_id":"smoke-%s","phone":"+380501234567","country":"UA","source":"smoke"}' "$(date +%s)")
TS=$(date +%s)
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$HMAC_SECRET" -hex | awk '{print $2}')
echo "→ POST $BASE_URL/v1/inbound/leads"
RESPONSE=$(curl -sS -w '\n%{http_code}' -X POST "$BASE_URL/v1/inbound/leads" \
-H "Authorization: Bearer $API_KEY" \
-H "X-Signature: sha256=$SIG" \
-H "X-Timestamp: $TS" \
-H "Content-Type: application/json" \
-d "$BODY")
CODE=$(tail -n1 <<<"$RESPONSE")
BODY_OUT=$(head -n-1 <<<"$RESPONSE")
echo "← HTTP $CODE"
echo "$BODY_OUT" | jq .
[[ "$CODE" =~ ^(200|409)$ ]] && echo "✓ OK" || (echo "✗ FAIL" >&2; exit 1)Кладёте в smoke.sh, запускаете перед боевой загрузкой — и сразу видно, что HMAC настроен правильно.