Developers

How to Connect an AI Calling Agent to Your CRM (API + Webhooks)

Shivam Yadav
Shivam Yadav
Co-Founder & Software Engineer, TaskVox AI
9 October 2026·9 min read
Quick answer

Use two pieces: an API call from your CRM or website that starts the AI call the moment a lead arrives, and a webhook that sends the result back. On TaskVox that is POST /api/campaigns with "autoStart": true to call, and a call.completed webhook — signed with HMAC-SHA256 — that delivers the transcript and outcome to your server.

The most valuable minute in sales is the first one after a lead fills in a form. This guide shows how to wire that up end to end. Everything below matches the live API at taskvox.in/api/docs.

The flow

  1. A lead is created in your CRM or website form.
  2. Your backend calls the TaskVox API to start a call to that number.
  3. The AI agent calls, asks your questions and ends the call.
  4. TaskVox POSTs a signed call.completed webhook to your server.
  5. Your server verifies the signature and updates the lead.

Step 1: get an API key

In the dashboard, open API Keys and create a key. It is shown once — keep it in your server’s secrets, never in browser or mobile code, because anyone holding it can place calls on your credits. Every request sends it in the X-API-Key header. Find the agent you will call with:

curl https://taskvox.in/api/agents \
  -H "X-API-Key: tvx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Step 2: start a call when a lead arrives

Create a campaign with the lead’s number and "autoStart": true. A number can be a plain string, or an object with variables your agent’s script can use, such as the lead’s name. Send an Idempotency-Key (for example your lead ID) so a network retry never calls the same person twice.

curl -X POST https://taskvox.in/api/campaigns \
  -H "X-API-Key: tvx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: lead-48213" \
  -d '{
    "name": "Website lead 48213",
    "agentId": "sales-agent-01",
    "numbers": [{ "number": "9198XXXXXXXX", "variables": { "name": "Rahul" } }],
    "autoStart": true
  }'

Two things trip up new integrations. Without autoStart (or a separate POST /api/campaigns/{id}/start), no call goes out. And campaign calls follow Indian calling rules: they only go out between 8 am and 8 pm IST, and numbers on your do-not-call list are skipped. Outside those hours the campaign is created but not started — the response has "started": false with a startError — and it does not start by itself later, so keep night-time leads in a queue and call POST /api/campaigns/{id}/start after 8 am.

Step 3: register a webhook

curl -X POST https://taskvox.in/api/webhooks \
  -H "X-API-Key: tvx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "name": "CRM sync", "url": "https://yourcrm.example.com/taskvox/webhook",
        "events": ["call.completed", "call.failed"] }'

The response includes the webhook’s secret, shown only once. Store it; you need it to verify every delivery. The four events are call.completed, call.failed, campaign.started and campaign.completed.

Step 4: verify and handle the webhook

Every delivery is a POST with an X-TaskVox-Signature header: an HMAC-SHA256 of the raw request body, hex-encoded, keyed with your secret. Verify it against the raw bytes, not the parsed JSON, and compare in constant time:

// Node.js + Express
const crypto = require('crypto');
app.post('/taskvox/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = crypto.createHmac('sha256', process.env.TASKVOX_WEBHOOK_SECRET)
    .update(req.body).digest('hex');
  const got = req.get('X-TaskVox-Signature') || '';
  if (got.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.status(401).send('bad signature');
  }
  res.sendStatus(200);                      // acknowledge first
  const evt = JSON.parse(req.body);         // then process
  if (evt.event === 'call.completed') updateLead(evt.data);
});

The data object of a call event carries call_id, agent_id, campaign_id, from, to, duration_seconds, turns, status, the full transcript as an array of { role, text } turns, a lead object (label hot / warm / cold / not_a_lead, score, summary and collected answers) and a recording_url.

Step 5: make it reliable

  • Acknowledge fast. Reply 2xx within 10 seconds and do the CRM update afterwards. A failed delivery is retried after about 1, 5 and 15 minutes.
  • Reconcile. If you must never miss a result, also pull GET /api/calls on a schedule and fill any gaps.
  • De-duplicate on the X-TaskVox-Delivery header or data.call_id — a retry carries the same values.
  • Mind the limits. Each API key may make 200 requests per minute; a 402 means the credit balance needs a recharge.
  • Keep keys server-side and rotate any key that may have leaked.

What to store in the CRM

  • The call ID and status, so you can link back to the recording in TaskVox.
  • The transcript, or the answers to your qualifying questions extracted from it.
  • The lead label (data.lead.label) and summary — the same Hot / Warm / Cold / Not a lead you see on the TaskVox Leads page.
  • A follow-up task for Hot leads — the faster a person calls back, the better.

Frequently asked questions

Is there an API to make AI voice calls?

Yes. With TaskVox you create a campaign through the API with one or more phone numbers and "autoStart": true, and an AI agent calls them. Requests are authenticated with an X-API-Key header, and results come back by webhook.

How do I send AI call results to my CRM?

Register a webhook URL for the call.completed event. After every call TaskVox POSTs a JSON payload with the call ID, numbers, duration, status and full transcript, signed with an HMAC-SHA256 signature you verify before updating the CRM.

Can I personalise each API call with the lead’s name?

Yes. Each entry in the numbers array can be an object such as {"number": "98XXXXXXXX", "variables": {"name": "Rahul"}}, and the agent’s script can use those variables.

Are webhooks retried if my server is down?

Yes. If your endpoint does not answer with a 2xx within 10 seconds, TaskVox sends the same event again after about 1, 5 and 15 minutes — 4 attempts in total. Every attempt carries the same X-TaskVox-Delivery ID, so you can ignore repeats. For a longer outage, reconcile with GET /api/calls.

Do API calls follow TRAI calling hours?

Yes. Campaigns created through the API follow the same rules as the dashboard: calls only go out between 8 am and 8 pm IST, and numbers on your do-not-call list are skipped. A campaign created outside those hours is not started, so queue it and start it after 8 am.

Shivam Yadav
Co-Founder & Software Engineer, TaskVox AI

Full-stack AI engineer specialising in voice AI, real-time communication systems and telephony. Built the TaskVox AI calling platform from the ground up. More articles →

Get an API key in two minutes

100 free credits to test · ₹2–₹4/min · telecom included

Read next