Get API Key

Audatec Voice AI

A programmable outbound call platform that lets your application trigger AI-powered phone conversations at scale. One API call — your agent handles the rest.

🤖
AI Agents
Configure conversational AI agents with custom scripts and per-call context injection.
Instant Dispatch
Calls are dispatched within seconds. SIP trunks handle hundreds of concurrent channels.
🔔
Real-time Results
Receive call outcomes via webhook or poll the status endpoint — your choice.

How it works

Every call flows through three components:

  • Agents — an AI persona with a script, voice, and expected input fields (e.g. customer_name, amount_due)
  • SIP Trunks — carrier lines with concurrency limits assigned to your org
  • Calls — a request that combines a phone number, an agent, a trunk, and per-call metadata

Base URL

Base URL
https://api.audatec.in/integration/v1
ℹ️ All requests must be made over HTTPS. HTTP requests will be rejected.

Authentication

Every request to the API must include an API key in the Authorization header.

API Key Format

Key structure
audtk_Wg8xJCrw-I6n3h48v6ZfTFgUzpADscHid36SCM

Using your key

Include your key in the Authorization header on every request:

HTTP Header
Authorization: Bearer audtk_your_key_here

Getting a key

Generate API keys from the Audatec Dashboard:

  1. Log in to studio.audatec.in
  2. Navigate to Settings → Integration
  3. Click New API Key, give it a name, and select a role
  4. Copy the key immediately — it is shown only once
⚠️ The raw key is shown exactly once at creation and cannot be retrieved again. Store it in a secrets manager immediately.

Key roles

Each key carries a role that controls what it can do:

viewer List agents & trunks, check call status
member Everything in viewer + trigger calls
admin Everything in member + manage webhooks
owner Unrestricted org-level access

Keys are org-scoped — a key authenticates as the organisation, not an individual user. All agents and trunks belonging to your org are accessible with a valid key.

Quick Start

Place your first AI call in three steps.

1
Get your agent ID
List available agents and note the id and required input_schema.fields.
curl
curl https://api.audatec.in/integration/v1/agents \
  -H "Authorization: Bearer $API_KEY"
2
Get your SIP trunk ID
List available trunks and note the id of an active one.
curl
curl https://api.audatec.in/integration/v1/sip-trunks \
  -H "Authorization: Bearer $API_KEY"
3
Trigger a call
Pass the phone number, agent, trunk, and any metadata the agent needs.
curl
curl -X POST https://api.audatec.in/integration/v1/calls \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+919876543210",
    "agent_id": "830f767a-397e-4b39-82ff-235cd344e2f9",
    "sip_trunk_id": "d5f3a1c0-8b2e-4f9a-b7d1-1e2c3a4b5c6d",
    "metadata": {
      "customer_name": "Rahul Sharma",
      "amount_due": "7500",
      "due_date": "2026-06-20"
    }
  }'
A successful response returns a call_id. Use it to poll /calls/{call_id}/status or set a callback_url to receive the result automatically.

List Agents

Returns all active AI agents available to your organisation, including the metadata fields each agent requires.

GET https://api.audatec.in/integration/v1/agents

Response — 200 OK

JSON
{
  "agents": [
    {
      "id": "830f767a-397e-4b39-82ff-235cd344e2f9",
      "name": "EMI Reminder Agent",
      "agent_code": "emi-reminder-v2",
      "status": "active",
      "input_schema": {
        "fields": ["customer_name", "amount_due", "due_date"],
        "sample_context": {
          "customer_name": "Rahul Sharma",
          "amount_due": "7500",
          "due_date": "2026-06-20"
        }
      }
    }
  ]
}

Response fields

FieldTypeDescription
idstringUnique agent UUID. Pass this as agent_id when triggering a call.
namestringHuman-readable display name.
agent_codestringInternal identifier used to dispatch the agent on the LiveKit server.
statusstringactive agents are available. Only active agents can be used to trigger calls.
input_schema.fieldsstring[]Keys that must be present in metadata when triggering a call with this agent.
input_schema.sample_contextobjectExample values showing the expected format for each field.

List SIP Trunks

Returns all active SIP trunks (carrier lines) allocated to your organisation, with their concurrency and rate limits.

GET https://api.audatec.in/integration/v1/sip-trunks

Response — 200 OK

JSON
{
  "sip_trunks": [
    {
      "id": "d5f3a1c0-8b2e-4f9a-b7d1-1e2c3a4b5c6d",
      "name": "India Prod Trunk 1",
      "trunk_phone": "+918069XXXXXX",
      "max_cps": 5,
      "max_channels": 100,
      "status": "active"
    }
  ]
}

Response fields

FieldTypeDescription
idstringUnique trunk UUID. Pass this as sip_trunk_id when triggering a call.
namestringDisplay name.
trunk_phonestringThe caller ID shown to the recipient.
max_cpsnumberMaximum calls per second this trunk accepts. Exceed it and you receive 429.
max_channelsnumberMaximum simultaneous active calls. Exceed it and you receive 429.
statusstringOnly active trunks can be used.

Trigger a Call

Dispatch a single outbound AI call. The call is queued immediately and your agent starts the conversation when the recipient answers.

POST https://api.audatec.in/integration/v1/calls

Request headers

HeaderRequiredDescription
AuthorizationrequiredBearer audtk_...
Content-Typerequiredapplication/json

Request body

ParameterTypeDescription
phone_numberrequired string The number to call. Must be in E.164 format — +919876543210 for India, +14155552671 for the US.
agent_idrequired string (UUID) ID of the agent that will handle the call. Obtain from List Agents.
sip_trunk_idrequired string (UUID) ID of the trunk to place the call through. Obtain from List SIP Trunks.
metadataconditional object Per-call variables injected into the agent's conversation (e.g. customer name, loan amount). Keys must match all entries in the agent's input_schema.fields. Required if the agent has any fields defined.
callback_urloptional string (URL) Your HTTPS endpoint. Audatec will POST the call result here when the call reaches a terminal state. See Call Notifications.

Example request

JSON body
{
  "phone_number": "+919876543210",
  "agent_id": "830f767a-397e-4b39-82ff-235cd344e2f9",
  "sip_trunk_id": "d5f3a1c0-8b2e-4f9a-b7d1-1e2c3a4b5c6d",
  "metadata": {
    "customer_name": "Rahul Sharma",
    "amount_due": "7500",
    "due_date": "2026-06-20"
  },
  "callback_url": "https://your-server.com/hooks/call-done"
}

Responses

201 Created Call accepted
JSON
{
  "call_id": "31106b7c-9d02-4723-8b07-5bb8d90240cb",
  "status": "triggered",
  "poll_url": "/integration/v1/calls/31106b7c-9d02-4723-8b07-5bb8d90240cb/status"
}
429 Trunk at capacity — check Retry-After header
JSON
{
  "error": "Trunk concurrency (max_channels) exhausted",
  "call_id": "31106b7c-9d02-4723-8b07-5bb8d90240cb",
  "status": "rejected"
}
💡 On a 429, read the Retry-After response header for the number of seconds to wait before retrying. Channels free up as live calls complete.

Get Call Status

Returns the current state and outcome of a call. Poll this endpoint until is_terminal is true.

GET https://api.audatec.in/integration/v1/calls/{call_id}/status

Path parameters

ParameterDescription
call_idrequiredThe UUID returned in the call_id field when you triggered the call.

Response — 200 OK

JSON
{
  "id": "31106b7c-9d02-4723-8b07-5bb8d90240cb",
  "phone_number": "+919876543210",
  "call_status": "Completed",
  "is_terminal": true,
  "stalled": false,
  "call_outcome": {
    "disposition": "interested",
    "summary": "Customer confirmed payment for June 20.",
    "sentiment": "positive"
  },
  "duration": 97,
  "start_timestamp": "2026-06-14T10:32:05.000Z",
  "end_timestamp": "2026-06-14T10:33:42.000Z",
  "transcript_url": null,
  "recording_url": null,
  "last_updated": "2026-06-14T10:33:42.000Z"
}

Response fields

FieldTypeDescription
call_statusstringCurrent status. See Call Status Values for the full table.
is_terminalbooleanStop polling when this is true. No further status changes will occur.
stalledbooleantrue if the call was answered but has not been updated in over 10 minutes — likely a stuck session.
call_outcomeobject | nullAI-determined result (disposition, summary, sentiment). Shape depends on agent configuration. null if the call did not connect.
durationnumber | nullCall duration in seconds. null for unanswered calls.
start_timestampstring | nullISO 8601 timestamp of when the recipient answered.
end_timestampstring | nullISO 8601 timestamp of when the call ended.
transcript_urlstring | nullLink to call transcript, if enabled for your account.
recording_urlstring | nullLink to call recording, if enabled for your account.

Call Notifications

Receive the call result instantly without polling by providing a callback_url when triggering the call. Audatec sends one POST to your endpoint when the call reaches a terminal state.

ℹ️ The callback fires once per call, only on terminal states (Completed, Declined, Failed, Rejected). It does not fire during the call.

Notification payload

JSON
{
  "event": "call.completed",
  "call_id": "31106b7c-9d02-4723-8b07-5bb8d90240cb",
  "call_status": "Completed",
  "call_outcome": {
    "disposition": "interested",
    "summary": "Customer confirmed payment for June 20.",
    "sentiment": "positive"
  },
  "duration": 97,
  "transcript_url": null,
  "recording_url": null,
  "metadata": {
    "customer_name": "Rahul Sharma",
    "amount_due": "7500",
    "due_date": "2026-06-20"
  },
  "occurred_at": "2026-06-14T10:33:42.000Z"
}
JSON
{
  "event": "call.failed",
  "call_id": "91a2b3c4-d5e6-7f8a-9b0c-1d2e3f4a5b6c",
  "call_status": "SIP Call Failed",
  "call_outcome": null,
  "duration": null,
  "transcript_url": null,
  "recording_url": null,
  "metadata": null,
  "occurred_at": "2026-06-14T11:05:10.000Z"
}

Event types

The event field will be one of:

call.completed call.failed call.rejected call.declined

Signature verification

Every notification includes an X-Audatec-Signature header — an HMAC-SHA256 of the request body signed with your account's webhook secret. Verify it before processing:

Node.js
const crypto = require('crypto');

function verifySignature(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Endpoint requirements

  • Must return HTTP 2xx within 30 seconds
  • If processing takes longer, respond 200 immediately and handle the payload asynchronously
  • Non-2xx responses and timeouts are retried

callback_url vs Polling

Two ways to receive call results. callback_url is strongly recommended for any production system.

callback_url Recommended

Pass a callback_url when triggering the call. Audatec POSTs the result to your endpoint the moment the call reaches a terminal state — no repeated requests, no delay, no wasted API quota.

  • Zero server load — one inbound POST replaces dozens of status polls per call
  • Instant — notification arrives within seconds of the call ending
  • Scales linearly — 1000 concurrent calls still means exactly 1000 callbacks, not 1000 × N polls
  • Verified with X-Audatec-Signature — HMAC-SHA256 so you can reject spoofed requests
💡 If your endpoint responds slowly, return 200 immediately and process the payload asynchronously. Audatec retries on non-2xx or timeout — so a fast ack prevents duplicate processing.

Polling

If you can't expose a public endpoint (local development, scripts, one-off jobs), poll GET /calls/{call_id}/status until is_terminal is true.

  • No inbound server required
  • Keep the interval at 4–5 seconds minimum — tighter loops waste quota without benefit
  • Stop immediately once is_terminal: true — further polls are no-ops
  • Not recommended at scale: 100 concurrent calls at 4 s intervals = 25 req/s of pure overhead
Node.js — polling loop
async function waitForCall(callId, apiKey) {
  const url = `https://api.audatec.in/integration/v1/calls/${callId}/status`;
  while (true) {
    const res = await fetch(url, {
      headers: { Authorization: `Bearer ${apiKey}` }
    });
    const data = await res.json();
    if (data.is_terminal) return data;
    await new Promise(r => setTimeout(r, 4000)); // poll every 4s
  }
}

Error Handling

All errors return JSON with an error field describing what went wrong.

Error response shape
{ "error": "metadata missing required keys: amount_due, due_date" }

Common errors

Error messageCauseFix
phone_number is requiredMissing or empty fieldInclude phone_number in E.164 format, e.g. +919876543210
metadata missing required keys: XAgent's required fields not all presentCheck input_schema.fields from GET /agents and include all keys
Agent is not activeAgent has been deactivatedUse GET /agents to find an active agent
SIP trunk is not activeTrunk is inactiveUse GET /sip-trunks to find an active trunk
callback_url must be a valid http or https URLMalformed URLEnsure URL starts with https:// or http://
Invalid or inactive API keyKey revoked or wrongGenerate a new key from Settings → Integration

Retry strategy

Different status codes call for different retry behaviour:

  • 400 — Do not retry. Fix the request payload.
  • 401 — Do not retry. Check your API key.
  • 429 — Retry after the Retry-After header value (seconds).
  • 502 / 503 — Retry with exponential backoff (1s, 2s, 4s…).

Call Status Values

All possible values for the call_status field.

Status Terminal? Meaning
Initiating ● In progress Call accepted and queued for dispatch
Ringing ● In progress Phone is ringing at the recipient's end
Answered ● In progress Recipient picked up — AI conversation underway
Completed ✓ Terminal Call ended normally. call_outcome is populated.
Decline ✓ Terminal Recipient declined the call or line was busy
Rejected — Capacity ✓ Terminal No available channels on the trunk at dispatch time
Trigger Failed ✓ Terminal Audatec could not initiate the call to the carrier
SIP Call Failed ✓ Terminal Carrier-level failure (no answer, network issue, SIP error)
ℹ️ When is_terminal is true, no further status changes will occur. The call_status field is the final state.

Error Codes

HTTP status codes returned by the API.

StatusNameWhen it occurs
201 Created Call accepted and queued successfully
400 Bad Request Invalid request — missing field, wrong format, metadata mismatch. The error field explains exactly what is wrong.
401 Unauthorized API key is missing, invalid, or has been revoked
404 Not Found The agent_id, sip_trunk_id, or call_id does not exist or does not belong to your org
429 Too Many Requests Trunk at full capacity. Wait the number of seconds in the Retry-After response header.
502 Bad Gateway The Audatec dialer is temporarily unavailable. Retry with exponential backoff.
503 Service Unavailable Authentication service temporarily unavailable. Retry after a short delay.