Creating Calls
HuskyVoice AI allows you to initiate voice conversations programmatically. You can trigger calls using either our REST API for custom applications or Inbound Webhooks for no-code tools.
Before You Begin
Make sure you have completed these three steps before initiating a call. If any of these are missing, your call will not go through.
Step 1 — Create an Outbound Agent
An Agent is your AI voice assistant — it handles the conversation on your behalf. You need at least one Outbound Agent set up in your HuskyVoice dashboard before making any calls.
Go to Dashboard → Agents → Create Agent and select Outbound as the type.
Step 2 — Assign a Phone Number to the Agent
Your agent needs a phone number to call from. Without an assigned number, calls cannot be placed.
Go to Dashboard → Agents → Select your Agent → Phone Numbers → Assign Number.
Step 3 — Generate an API Key
An API Key is a unique password that lets your application talk to HuskyVoice securely. You need this to authenticate your requests.
Go to Dashboard → Integrations → API Keys → Generate New Key. Copy and store it safely — it will not be shown again.
If you are using a no-code tool like Zapier or HubSpot, you only need Steps 1 and 2. Use the Inbound Webhook tab below instead of the REST API.
- REST API (API Keys)
- Inbound Webhook
1. Using the REST API
Best for developers building custom applications. Authenticate using your API Key.
- cURL
- Python
- JavaScript
- n8n
curl -s -X POST https://api.huskyvoice.ai/v1/calls \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agent_123",
"user_number": "+91XXXXXXXXXX",
"user_name": "John Doe",
"user_email": "john.doe@example.com",
"scheduled_time": "2026-07-15T18:30:00Z",
"additional_info": {
"purpose": "Appointment Confirmation"
}
}'
import requests
url = "https://api.huskyvoice.ai/v1/calls"
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"agent_id": "agent_123",
"user_number": "+91XXXXXXXXXX",
"user_name": "John Doe",
"user_email": "john.doe@example.com",
"scheduled_time": "2026-07-15T18:30:00Z",
"additional_info": {
"purpose": "Appointment Confirmation"
}
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const response = await fetch("https://api.huskyvoice.ai/v1/calls", {
method: "POST",
headers: {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
agent_id: "agent_123",
user_number: "+91XXXXXXXXXX",
user_name: "John Doe",
user_email: "john.doe@example.com",
scheduled_time: "2026-07-15T18:30:00Z",
additional_info: {
purpose: "Appointment Confirmation"
}
})
});
const data = await response.json();
console.log(data);
Create an HTTP Header Auth credential in n8n: set Name to x-api-key and Value to YOUR_API_KEY. Select it in the HTTP Request node's Authentication field.
{
"name": "HuskyVoice – Create Call",
"nodes": [
{
"parameters": {
"method": "POST",
"url": "https://api.huskyvoice.ai/v1/calls",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\n \"agent_id\": \"agent_123\",\n \"user_number\": \"+919845251123\",\n \"user_name\": \"Rajesh\",\n \"user_email\": \"rajesh@example.com\",\n \"scheduled_time\": \"2026-07-15T18:30:00Z\",\n \"additional_info\": {\n \"purpose\": \"Appointment Confirmation\"\n }\n}"
},
"id": "1",
"name": "Create Call",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [250, 300]
}
],
"connections": {},
"settings": {},
"meta": { "instanceId": "huskyvoice-docs" }
}
Sample Response:
{
"data": {
"call_id": "call_abc123",
"scheduled_at": "2024-01-27T03:02:00.000Z",
"status": "queued"
}
}
2. Using Inbound Webhooks
Ideal for Zapier, HubSpot, or any system that can send a POST request.
- Endpoint:
https://api.huskyvoice.ai/v1/hooks/{YOUR_SECRET_TOKEN} - Method:
POST
- cURL
- Python
- JavaScript
- n8n
curl -X POST https://api.huskyvoice.ai/v1/hooks/YOUR_SECRET_TOKEN \
-H "Content-Type: application/json" \
-d '{
"action": "call.create",
"data": {
"agent_id": "agent_123",
"contact_number": "+1234567890",
"contact_name": "Charlie"
}
}'
import requests
url = "https://api.huskyvoice.ai/v1/hooks/YOUR_SECRET_TOKEN"
payload = {
"action": "call.create",
"data": {
"agent_id": "agent_123",
"contact_number": "+1234567890",
"contact_name": "Charlie"
}
}
response = requests.post(url, json=payload)
print(response.json())
const response = await fetch(
"https://api.huskyvoice.ai/v1/hooks/YOUR_SECRET_TOKEN",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
action: "call.create",
data: {
agent_id: "agent_123",
contact_number: "+1234567890",
contact_name: "Charlie"
}
})
}
);
const data = await response.json();
console.log(data);
Authentication uses the secret token embedded in the URL. No separate credential setup is required in n8n.
{
"name": "HuskyVoice – Trigger Call via Inbound Webhook",
"nodes": [
{
"parameters": {
"method": "POST",
"url": "https://api.huskyvoice.ai/v1/hooks/YOUR_SECRET_TOKEN",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\n \"action\": \"call.create\",\n \"data\": {\n \"agent_id\": \"agent_123\",\n \"contact_number\": \"+1234567890\",\n \"contact_name\": \"Charlie\"\n }\n}"
},
"id": "1",
"name": "Trigger Call",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [250, 300]
}
],
"connections": {},
"settings": {},
"meta": { "instanceId": "huskyvoice-docs" }
}
What Happens Next?
Once your call is initiated, HuskyVoice queues it and connects the agent to the contact. You can track the live status and outcome of the call via Call Status.
Save the call_id from the response — you'll need it to fetch status updates or cancel the call later.
Technical Details
| Field | Required | Description |
|---|---|---|
agent_id | Yes | The unique ID of the AI agent to use for this call. |
user_number | Yes | The target phone number with country code (e.g., +91XXXXXXXXXX). |
user_name | No | The user's name. |
user_email | No | The user's email address. |
additional_info | No | A JSON object containing variables your agent can reference during the call. |
scheduled_time | No | ISO 8601 timestamp for when the call should be placed. Must include an explicit UTC offset and be in the future. Defaults to immediate (~15 seconds after the request) if omitted. |
contact_number, contact_name, and contact_email are still accepted as aliases for
user_number, user_name, and user_email for backward compatibility — new integrations
should use the user_* names. Don't send both names for the same field in one request.
Use scheduled_time to queue a call for a specific future time instead of immediately — for example, a reminder call an hour before an appointment. The call will be placed at that time rather than right away.
scheduled_time must end in Z (UTC) or an explicit offset like +05:30 — for example 2026-07-15T18:30:00Z or 2026-07-15T18:30:00+05:30. Bare timestamps with no offset (e.g. 2026-07-15T18:30:00) are rejected with a 400 error, because they would otherwise be interpreted using the server's local timezone rather than yours — the same string could resolve to a different actual call time depending on which server processes it. Always specify the offset explicitly to avoid this ambiguity.
Using additional_info in Your Agent Prompt
The fields you pass in additional_info can be used directly inside your agent's prompt using double curly braces {{ }}. This lets your agent personalise the conversation for each contact.
Example — passing additional info in the API call:
{
"agent_id": "agent_123",
"user_number": "+91XXXXXXXXXX",
"user_name": "John Doe",
"user_email": "john.doe@example.com",
"additional_info": {
"purpose": "Appointment Confirmation"
}
}
Example — referencing them inside your agent prompt:
Hi, this call is regarding: {{purpose}}. Please confirm if you will be attending.
What the agent will say:
"Hi, this call is regarding: Appointment Confirmation. Please confirm if you will be attending."
You can pass up to 25 key-value pairs in additional_info. Use clear, descriptive key names so your agent prompt stays readable.