Call tracking integration

Your call platform keeps doing what it does. It just also tells us about each call: one webhook, one payload. We match the caller to your Keap contact and attribute the call by the number they dialed, so phone leads show up in your report next to your web leads.

Your webhook URL

It's on your setup page, under "Track phone calls too" — copy it from there. It looks like this:

https://t.myvitalassistant.com/call?a=YOUR_ACCOUNT&k=YOUR_KEY

The key in the URL is your account's ingest key. It can only submit data, never read any, but treat the URL like a password all the same.

The payload

POST JSON to your webhook URL, one call per request:

{
  "external_id":     "CAL-8842",
  "started_at":      "2026-08-01T14:32:00Z",
  "caller":          "+1 727 555 0101",
  "dialed":          "(813) 555-0200",
  "duration_s":      184,
  "disposition":     "answered",
  "source_platform": "callrail",
  "source_hint":     "google-brand",
  "recording_url":   "https://…",
  "transcript":      "…"
}
FieldWhat it is
external_id requiredYour platform's own id for the call. This is the dedupe key: retries and repeat deliveries of the same id are safe.
started_at requiredWhen the call started, as ISO 8601 or unix seconds.
caller one of these twoThe caller's number, any common format. We normalize it and match it against your Keap contacts.
dialed one of these twoThe number they called. This is what attributes the call: you tell us once which tracking number belongs to which ad source, and every call to it is credited there.
duration_sCall length in seconds.
dispositionanswered, missed, or voicemail.
source_platformName of the sending platform, for your own reading later.
source_hintIf your platform already knows the call's marketing source (Marchex and CallRail often do), send it here. It takes precedence over the dialed-number mapping.
recording_url, transcriptOptional, stored with the call.

Responses

StatusMeaning
200Stored. {"ok":true,"id":"CAL-8842"}
400The payload is missing something; the body says exactly what. The raw payload is kept either way so nothing is lost while you fix the mapping.
401Wrong or missing key. Re-copy the URL from your setup page.
500Our storage hiccupped. Retry: it's safe, thanks to external_id dedupe.

Try it from a terminal

curl -X POST "YOUR_WEBHOOK_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "test-1",
    "started_at":  "2026-08-01T14:32:00Z",
    "caller":      "+17275550101",
    "dialed":      "+18135550200",
    "duration_s":  60,
    "disposition": "answered"
  }'

The call appears on your dashboard's CALLS card after the next daily refresh.

Hooking up common platforms

The number-to-source map. Tracking numbers only attribute calls if we know what each one means: this number is on your Google ads, this one is on the truck. Send us your list once (number → source, and campaign if you have one) and we configure it on your account. Changing it later is one email.

Privacy

Caller numbers are used to match calls to your own Keap contacts and for nothing else. Recordings and transcripts are stored only if you send them. Everything lives in your account's partition and shows only on your token-protected dashboard.