Salesforce call tracking integration

The quickest path into Salesforce is Zapier: our webhook triggers a Zap that upserts a Lead by phone and logs a completed call Task. Teams with admin resources can instead point the webhook at a Salesforce Flow with an HTTP-callout-enabled endpoint.

Integrations / Salesforce

What you get

Every qualified call (passing your duration and screening rules) is delivered to Salesforce within about a minute: caller number, duration, timestamps, the campaign that generated the call, ad click IDs when present, and a recording link.

Step A — callstracking.com side

  1. Create an account and set up your campaign (2 minutes).
  2. Go to Dashboard → Integrations → Webhook / CRM.
  3. Paste the webhook URL from Salesforce (Step B) and choose a signing secret.
  4. Save. Qualified calls now POST to that URL automatically.

Step B — Salesforce side

  1. In Zapier, create a Zap with trigger "Webhooks by Zapier → Catch Hook". Copy the hook URL.
  2. Paste it into the callstracking.com webhook integration (Step A above) and save.
  3. Make a qualified test call so Zapier captures the payload.
  4. Add action "Salesforce → Find Record (Lead)" by phone = fromE164, with a Create Lead fallback.
  5. Add action "Salesforce → Create Record (Task)": type Call, status Completed, subject = campaignName, related to the lead.
  6. Turn the Zap on.

The payload

Sent as JSON with content-type application/json. The recordingUrl opens in a signed-in callstracking.com session.

{
  "type": "qualified_call",
  "callId": "clx1abc...",
  "source": "DNI",
  "startedAt": "2026-08-14T17:21:09.000Z",
  "qualifiedAt": "2026-08-14T17:23:41.000Z",
  "durationSec": 152,
  "fromE164": "+15551234567",
  "toE164": "+12138321924",
  "campaignId": "cmsam...",
  "campaignName": "Google Ads — Plumbing",
  "channel": "GOOGLE_ADS",
  "recordingUrl": "https://callstracking.com/api/recordings/clx1abc...",
  "clickIds": { "gclid": "..." },
  "utm": { "utm_source": "google", "utm_campaign": "plumbing" }
}

Verifying the signature

Every delivery is signed with your secret: header x-ct-signature: sha256=<hmac> over the raw body, plus x-ct-event: call.qualified. Platforms like Zapier and GoHighLevel can skip verification (the URL itself is secret); verify when posting to your own server:

// Node.js — verify the x-ct-signature header
import { createHmac } from "node:crypto";

const expected = "sha256=" +
  createHmac("sha256", process.env.CT_WEBHOOK_SECRET)
    .update(rawRequestBody)   // the exact raw body string
    .digest("hex");

const valid = expected === req.headers["x-ct-signature"];

Troubleshooting