LPLeadProof

ElevenLabs post-call CRM delivery

Deliver every ElevenLabs post-call lead to the CRM exactly once.

Verify signed ElevenLabs post-call events, queue only approved data collection results, and turn each qualified conversation into a duplicate-safe CRM delivery receipt.

Protect 25 live leads free →Start Builder · $49/monthAudit this workflow
Paid plan uses secure Stripe checkout · plan assigned after verified payment · activate with the checkout email
THE FAILURE GAP

A successful automation run is not proof of delivery.

ElevenLabs sends post_call_transcription only after the call and analysis are complete, but a successful webhook receipt still does not prove the CRM stored the qualified lead. The handler must verify the ElevenLabs-Signature against the untouched body, select only authorized data_collection_results, acknowledge promptly, and preserve conversation_id across retries.

ElevenLabs post_call_transcription -> signed mapping handler -> durable queue -> LeadProof -> CRM
01

Webhook receipt is not CRM proof

Returning 200 confirms receipt by the handler, not that the downstream sales system accepted the qualified lead.

02

Retries can repeat the same conversation

ElevenLabs documents identical retry payloads, so conversation_id must remain the stable identity through every delivery attempt.

03

The event contains more than sales needs

The post-call event can include extensive call artifacts; the CRM handoff should select only approved data collection results.

Implementation

Put LeadProof in the delivery path.

Keep the tools that create and process the lead. Standardize only the fragile handoff between them.

Platform reference: ElevenLabs post-call webhook documentationOpen sandbox instructions →
  1. Configure a post_call_transcription webhook in ElevenLabs and keep its generated HMAC secret in server-side environment storage.
  2. Read the untouched request body, verify ElevenLabs-Signature with the official SDK constructEvent helper, and accept only the expected event type.
  3. Select named values from data.analysis.data_collection_results, carry data.conversation_id into a compact durable queue job, and return HTTP 200 promptly.
  4. Let the worker send the selected lead through LeadProof with conversation_id as the Idempotency-Key, then retain the delivery receipt for reconciliation.
POSThttps://leadproof.jessesay.chatgpt.site/api/v1/leads
import { ElevenLabsClient } from "elevenlabs";

const elevenlabs = new ElevenLabsClient();

export async function POST(request: Request) {
  const rawBody = await request.text();
  const signature = request.headers.get("ElevenLabs-Signature");

  let event;
  try {
    event = await elevenlabs.webhooks.constructEvent(
      rawBody,
      signature,
      process.env.ELEVENLABS_WEBHOOK_SECRET
    );
  } catch {
    return Response.json({ error: "Invalid signature" }, { status: 401 });
  }

  if (event.type !== "post_call_transcription") {
    return Response.json({ received: true }, { status: 200 });
  }

  const conversationId = event.data?.conversation_id;
  const fields = event.data?.analysis?.data_collection_results;
  const lead = {
    name: fields?.name?.value,
    email: fields?.email?.value,
    phone: fields?.phone?.value
  };

  if (conversationId && lead.name && lead.email) {
    await deliveryQueue.send({ conversationId, lead });
  }

  return Response.json({ received: true }, { status: 200 });
}

export async function deliverElevenLabsLead({ conversationId, lead }) {
  const response = await fetch(
    "https://leadproof.jessesay.chatgpt.site/api/v1/leads",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.LEADPROOF_API_KEY}`,
        "Content-Type": "application/json",
        "Idempotency-Key": conversationId
      },
      body: JSON.stringify({
        destination: process.env.CRM_WEBHOOK_URL,
        ...lead,
        source: "elevenlabs_post_call"
      })
    }
  );

  if (!response.ok) throw new Error("Lead delivery failed");
  const delivery = await response.json();
  await persistReceipt(conversationId, delivery.receipt?.id);
}

Questions

What teams ask before adding LeadProof.

Why use post_call_transcription?

ElevenLabs documents this event as occurring after a call finishes and analysis is complete, which is when data collection results are available.

What happens when ElevenLabs retries?

The retry payload is identical, but the same conversation_id becomes the LeadProof Idempotency-Key so the CRM write remains duplicate-safe.

Does the example copy the complete conversation?

No. It reads only named values from data_collection_results and places those approved fields in the delivery job.

FREE · NO SIGNUP

See the gaps in your real workflow.

Get an explainable risk score, prioritized fixes, and the right LeadProof plan.

Protect 25 live leads free →Run the reliability auditStart Builder · $49/month