Developers

Place a call with one POST. Know the outcome seconds after hangup.

A REST API at api.voicecallingai.com — Bearer keys, JSON over HTTPS, HMAC-signed webhooks. Your system asks for a call; our agent makes it; the outcome and summary land back on your endpoint.

API access is included on the Scale and Enterprise plans.

The loop

One POST out, one signed webhook back

01 · Place the call

# Place a call — the agent dials, talks, and reports back
curl -X POST https://api.voicecallingai.com/v1/calls \
  -H "Authorization: Bearer $VCA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "AGENT_UUID",
    "to": "+9198xxxxxxxx",
    "external_ref": "lead-4812"
  }'

# 202 → { "status": "queued", ... }
# DND, consent and calling-hours checks run before dial — and again at dial time.

02 · Verify and use the outcome

// Webhooks are signed: X-VCA-Signature: t=<unix>,v1=<hex>
// where v1 = HMAC_SHA256(signing_secret, `${t}.` + raw_body)
const crypto = require("crypto");

function verifyVcaSignature(sigHeader, rawBody, secret) {
  const { t, v1 } = Object.fromEntries(
    sigHeader.split(",").map((p) => p.split("="))
  );
  const expected = crypto.createHmac("sha256", secret) // secret = "whsec_..."
    .update(`${t}.`).update(rawBody).digest("hex");
  const a = Buffer.from(expected), b = Buffer.from(v1 || "");
  return a.length === b.length && crypto.timingSafeEqual(a, b)
    && Math.abs(Date.now() / 1000 - Number(t)) <= 300; // reject stale timestamps
}

// seconds after hangup:
// { "type": "call.completed", "data": { "outcome": "...", "summary": "...", ... } }
Events:
  • call.ringing
  • call.answered
  • call.completed
  • call.failed
  • call.no_answer
  • call.busy

Production-ready

The boring parts, done properly

  • 120 requests/min per key

    Every response carries X-RateLimit headers; 429s include Retry-After. Higher limits on Enterprise.

  • Retries that behave

    Webhook deliveries retry with backoff (60s → 480s, 5 attempts). Repeated failures auto-disable the subscription and flag it in the dashboard.

  • Compliance in the API

    Requests that would break the rules are rejected — DND, withdrawn consent and calling hours are checked before queueing and again at dial time.

  • Idempotency built in

    Send an idempotency key with each call request and safely retry — replays return the original, no double-dial.

Keys live in your dashboard

On Scale or Enterprise, open Integrations → API Keys, create a key, and make your first call from the quickstart in about ten minutes.