Skip to main content

API Keys

Authentication, endpoints, request formats, and response examples for the v1/calls API

Overview​

API keys give external systems programmatic access to trigger, retrieve, and cancel voice calls. Each key is scoped to specific permissions — only grant what your integration actually needs.

note

Indian (+91XXXXXXXXXX) and US (+1XXXXXXXXXX) phone numbers in E.164 format are currently supported.

Plan limits

The Base plan allows up to 5 active API keys per organization. Professional and Enterprise plans have no limit. Revoked keys don't count toward the limit.

Base URL​

https://api.huskyvoice.ai/v1

Authentication​

Include your API key in the x-api-key header of every request.

x-api-key: sk_live_your_api_key_here
Content-Type: application/json
caution

Security: Store your API key in an environment variable. Never hardcode it in source code or commit it to version control.

Permissions (Scopes)​

Each API key is created with one or more scopes. Grant only the scopes your integration requires.

ScopeAllows
calls:createSchedule new voice calls via POST /v1/calls
calls:readRetrieve call status and details via GET /v1/calls/:id
calls:cancelCancel pending calls via POST /v1/calls/:id/cancel
calls:deletePermanently delete a call and erase customer PII via DELETE /v1/calls/:id
appointments:readFetch appointments, configuration, services, and availability
appointments:writeCreate and update appointments
slots:readRead slot availability and schedule tracking records
slots:writeCreate, update, and disable calendar windows; update and regenerate tracking

Endpoints​

Schedule a call​

POST /v1/calls Requires calls:create scope

Schedule a voice call with an agent. Supports idempotent creation via the Idempotency-Key header.

Request Body​
{
"agent_id": "agent_123", // required
"user_number": "+919876543210", // required — E.164 format, +91 or +1
"user_name": "Raj Patel", // optional
"user_email": "raj@company.com", // optional
"user_preferred_language": "hindi", // optional — overrides the agent's default language for this call
"additional_info": { // optional — custom key-value pairs
"company": "Acme Corp",
"deal_stage": "negotiation"
}
}
Legacy field names

contact_number, contact_name, contact_email, and contact_preferred_language are still accepted as aliases for user_number, user_name, user_email, and user_preferred_language respectively, for backward compatibility with existing integrations. New integrations should use the user_* names. A request must not send both names for the same field (e.g. both contact_number and user_number) — that returns a 400 VALIDATION_ERROR.

Response — 201 Created​
{
"data": {
"call_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "scheduled"
}
}

Retrieve call status​

GET /v1/calls/:call_id Requires calls:read scope

Retrieve status and details for a specific call.

Response — 200 OK​
{
"data": {
"call_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "scheduled", // scheduled | in_progress | completed | failed | cancelled
"call_direction": "outbound", // outbound | inbound
"call_to": "+919876543210",
"call_from": null, // populated instead for inbound calls; call_to is null there
"call_duration_seconds": null,
"agent_id": "agent_123",
"agent_name": "Sales Agent",
"call_recording": "https://studio.huskyvoice.ai/spark/calls/550e8400-e29b-41d4-a716-446655440000",
"call_analytics": null,
"call_transcript": null,
"call_triggered_at": null,
"scheduled_at": "2024-01-27T03:02:00.000Z",
"completed_at": null,
"error": null
}
}

Cancel a call​

POST /v1/calls/:call_id/cancel Requires calls:cancel scope

Cancel a call in pending or scheduled status. Returns 409 if already started or completed.

Response — 200 OK​
{
"data": {
"call_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "cancelled",
"cancelled_at": "2024-01-27T03:01:00.000Z"
}
}

Delete a call​

DELETE /v1/calls/:call_id Requires calls:delete scope

Permanently deletes a completed call and erases all associated end-customer PII (transcript, contact details, recording metadata). Only works on calls that have a recorded engagement. Returns 404 if the call is not found. See Deleting Calls for full details.

Response — 200 OK​
{
"data": {
"call_id": "550e8400-e29b-41d4-a716-446655440000",
"deleted": true
}
}

Error Codes​

CodeMeaning
400Bad request — missing or invalid fields in the request body
401Unauthorized — missing or invalid API key
403Forbidden — API key does not have the required scope
409Conflict — call cannot be cancelled because it has already started or completed
422Unprocessable entity — invalid phone number format or unsupported country code
429Rate limit exceeded — slow down requests and retry after the indicated delay

Examples​

Full working scripts covering create, status check, and cancel.

#!/bin/bash
API_KEY="$APPEQ_API_KEY"
BASE_URL="https://api.huskyvoice.ai/v1"

# ── Create a call ──────────────────────────────────────────────────────────
CALL_ID=$(curl -s -X POST "$BASE_URL/calls" \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agent_123",
"user_number": "+919876543210",
"user_name": "Raj Patel",
"user_email": "raj@company.com",
"additional_info": {"company": "Acme Corp", "deal_stage": "negotiation"}
}' | jq -r '.data.call_id')
echo "Created: $CALL_ID"

# ── Get call status ────────────────────────────────────────────────────────
STATUS=$(curl -s "$BASE_URL/calls/$CALL_ID" \
-H "x-api-key: $API_KEY" | jq -r '.data.status')
echo "Status: $STATUS"

# ── Cancel a call ──────────────────────────────────────────────────────────
CANCEL_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST "$BASE_URL/calls/$CALL_ID/cancel" \
-H "x-api-key: $API_KEY")
if [ "$CANCEL_STATUS" = "409" ]; then
echo "Cannot cancel — call already started or completed"
else
echo "Cancelled successfully"
fi