Обсудить задачу

Prooflytics + Quora Ads: атрибуция B2B-лидов из intent-based рекламы до закрытой сделки

Quora Ads - intent-based рекламная платформа: объявления показываются пользователям, которые уже задают конкретные профессиональные вопросы. Для B2B SaaS это целевой трафик: если ваш продукт решает проблему, по которой есть активный Quora-тред, объявление видит именно тот, кто ищет решение прямо сейчас.

Проблема стандартной атрибуции Quora Ads: Quora Pixel фиксирует конверсию при заполнении формы или переходе на Thank You страницу. Но в B2B цикл сделки 30-90 дней. Pixel видит “лид создан”, но не знает - закрылся ли этот лид в сделку через месяц. Quora отчитывается по CPA лида, а реальный CPA закрытой сделки (CPO) неизвестен.

Prooflytics решает эту задачу: соединяет Quora click ID (qclid) с данными CRM, отслеживает движение по воронке и передаёт back в Quora Conversions API событие purchase (или кастомный “deal_won”) когда сделка закрывается.

Quora qclid - уникальный идентификатор клика, который Quora добавляет к URL при переходе с рекламы. Аналог gclid (Google) и fbclid (Meta). Сохраняется при первом визите и хранится в CRM для последующей атрибуции.

Архитектура атрибуции

Код
Пользователь кликает на Quora рекламу
  -> URL: yoursite.com/demo?qclid=AaBbCcDd...
  -> Pixel js + кастомный код сохраняют qclid в cookie + localStorage

Форма заявки
  -> qclid передаётся как hidden field
  -> Kommo/HubSpot: сделка создана, qclid сохранён в custom field

Prooflytics
  -> Периодически читает статусы сделок из CRM
  -> При Closed Won: находит сделки с qclid
  -> Quora Conversions API: event "purchase" с qclid
  -> Quora отчитывает реальный CPO

Захват qclid на сайте

JavaScript
// Добавить на все landing pages
(function() {
    var params = new URLSearchParams(window.location.search);
    var qclid  = params.get("qclid");
    if (qclid) {
        localStorage.setItem("qclid", qclid);
        document.cookie = "qclid=" + qclid + ";path=/;max-age=2592000";  // 30 дней
    }
})();

// При отправке формы
function getQclid() {
    var params = new URLSearchParams(window.location.search);
    return params.get("qclid") || localStorage.getItem("qclid") || getCookie("qclid") || "";
}

function getCookie(name) {
    var match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
    return match ? match[2] : "";
}

// В форму заявки добавить hidden input
// <input type="hidden" name="qclid" id="field_qclid" />
document.getElementById("field_qclid").value = getQclid();

Передача qclid в Quora Conversions API при закрытии сделки

Python
import requests, os, hashlib, time
from flask import Flask, request, jsonify

app = Flask(__name__)

QUORA_PIXEL_ID    = os.environ["QUORA_PIXEL_ID"]
QUORA_ACCESS_TOKEN = os.environ["QUORA_ACCESS_TOKEN"]
KOMMO_SUBDOMAIN   = os.environ["KOMMO_SUBDOMAIN"]
KOMMO_TOKEN       = os.environ["KOMMO_ACCESS_TOKEN"]
KOMMO_CF_QCLID    = int(os.environ["KOMMO_CF_QCLID_ID"])
CLOSED_WON_ID     = int(os.environ["KOMMO_CLOSED_WON_ID"])

QUORA_API_BASE = "https://api.quora.com/conversion/pixel/log"
KOMMO_BASE     = f"https://{KOMMO_SUBDOMAIN}.kommo.com/api/v4"
KOMMO_HDR      = {"Authorization": f"Bearer {KOMMO_TOKEN}", "Content-Type": "application/json"}

def sha256_email(email: str) -> str:
    return hashlib.sha256(email.strip().lower().encode()).hexdigest()

def get_lead_qclid_and_email(lead_id: int) -> tuple[str, str]:
    r = requests.get(
        f"{KOMMO_BASE}/leads/{lead_id}",
        headers=KOMMO_HDR,
        params={"with": "contacts,custom_fields_values"},
    )
    lead = r.json()
    qclid = ""
    for cf in lead.get("custom_fields_values", []) or []:
        if cf.get("field_id") == KOMMO_CF_QCLID:
            vals = cf.get("values", [])
            if vals:
                qclid = vals[0].get("value", "")
                break

    email = ""
    contacts = lead.get("_embedded", {}).get("contacts", [])
    if contacts:
        rc = requests.get(
            f"{KOMMO_BASE}/contacts/{contacts[0]['id']}",
            headers=KOMMO_HDR,
            params={"with": "custom_fields_values"},
        )
        for cf in rc.json().get("custom_fields_values", []) or []:
            if cf.get("field_code") == "EMAIL":
                vals = cf.get("values", [])
                if vals:
                    email = vals[0].get("value", "")
                    break

    return qclid, email

def send_quora_conversion(qclid: str, email: str, revenue: float):
    payload = {
        "pixel_id":   QUORA_PIXEL_ID,
        "event_name": "Purchase",
        "event_id":   f"deal_won_{qclid}_{int(time.time())}",
        "event_time": int(time.time()),
        "user_data": {
            "email":   [sha256_email(email)] if email else [],
            "click_id": qclid,
        },
        "custom_data": {
            "currency": "USD",
            "value":    round(revenue, 2),
        },
    }
    r = requests.post(
        QUORA_API_BASE,
        headers={"Authorization": f"Bearer {QUORA_ACCESS_TOKEN}", "Content-Type": "application/json"},
        json=[payload],
    )
    return r.status_code, r.text

@app.route("/webhooks/kommo", methods=["POST"])
def kommo_webhook():
    data = request.json or {}
    for lead_data in data.get("leads", {}).get("status", []):
        lead_id    = lead_data.get("id")
        new_status = lead_data.get("status_id")
        if new_status != CLOSED_WON_ID:
            continue

        r_lead = requests.get(f"{KOMMO_BASE}/leads/{lead_id}", headers=KOMMO_HDR)
        revenue = float(r_lead.json().get("price") or 0)

        qclid, email = get_lead_qclid_and_email(lead_id)
        if not qclid:
            continue  # нет Quora-клика - не отправляем

        status, resp = send_quora_conversion(qclid, email, revenue)
        requests.post(
            f"{KOMMO_BASE}/notes",
            headers=KOMMO_HDR,
            json=[{
                "entity_id":   lead_id,
                "entity_type": "leads",
                "note_type":   "common",
                "params":      {"text": f"Quora Conversions API: event Purchase отправлен. Status: {status}. qclid: {qclid}"},
            }],
        )

    return jsonify({"status": "ok"}), 200

Custom Event vs Purchase

Quora поддерживает стандартные события (Purchase, Lead, Complete Registration) и кастомные. Для B2B лучше разделить:

  • Lead - при создании сделки в CRM (MQL)
  • Purchase - при Closed Won (Revenue)

Так Quora понимает оба этапа воронки и может оптимизировать кампании под реальные конверсии.

Роль Prooflytics в этой схеме

Prooflytics - attribution middleware: единое хранилище touch-данных (qclid, fbclid, gclid, UTM) из всех рекламных каналов, синхронизированное с CRM. При закрытии сделки Prooflytics автоматически определяет источники по multi-touch модели и отправляет события в каждый рекламный канал через соответствующий Conversions API.

В примере выше - упрощённая реализация для single-channel (Quora). Для multi-channel атрибуции (Quora + Meta + LinkedIn + Google одновременно) описан полный цикл в статье Prooflytics + Amazon DSP.

Для кого актуально

B2B SaaS с целевой аудиторией, активно задающей профессиональные вопросы на Quora (IT, SaaS, маркетинг, продажи, HR). Quora Ads эффективны если продукт решает конкретный вопрос - а не просто таргетирует демографию. Для Russian-speaking фаундеров на международном рынке: английский Quora имеет значительную аудиторию IT-специалистов и менеджеров из США и ЕС.

Часто задаваемые вопросы

Как долго хранить qclid в CRM?

qclid валиден для Quora Conversions API в течение 28 дней с момента клика (аналог окна атрибуции Google/Meta). Если сделка закрывается позже - конверсия не будет атрибутирована Quora корректно. Храните qclid бессрочно: даже если атрибуция не пройдёт через API, данные полезны для внутренней аналитики.

Quora Conversions API требует верификацию домена?

Да, аналог Meta. В Quora Ads Manager: Pixels -> Setup -> Verify Domain. Нужно добавить meta-тег или DNS-запись. Без верификации Conversions API может отклонять события.

Как Quora Ads сравниваются по CPL с LinkedIn Ads для B2B?

Quora CPL обычно ниже LinkedIn ($20-50 vs $80-200 для B2B SaaS), но конверсия в сделку может быть ниже из-за менее точного таргетинга. Оптимальная стратегия: использовать Quora для верхушки воронки (awareness + MQL), LinkedIn для lower-funnel (директора и C-level ретаргетинг). Multi-channel атрибуция через Prooflytics покажет реальный ROI каждого канала.

Итог

Prooflytics + Quora Ads - замыкание петли атрибуции:

  • Захват qclid на посадочной странице -> сохранение в cookie + localStorage
  • qclid в hidden field формы -> CRM custom field
  • Webhook Closed Won -> send_quora_conversion(qclid, email, revenue)
  • event_name: Purchase, user_data.click_id: qclid, SHA256 email
  • Custom event Lead при создании сделки для оптимизации кампании под MQL

Если нужна настройка multi-channel атрибуции с Quora Ads и другими платформами через Prooflytics - опишите задачу команде Exceltic.dev.

Ещё статьи

Все →