---
title: "Initiate an outbound call with AI agent"
method: POST
path: "/api/v1/phones/calls/initiate-call"
tags: ["Phones - Calls"]
---

# Initiate an outbound call with AI agent

`POST /api/v1/phones/calls/initiate-call`

## Request

- Base URL: `https://api.voicelogica.ai`
- URL: `https://api.voicelogica.ai/api/v1/phones/calls/initiate-call`
- Auth: API key in header `x-api-key`

Initiate an outbound call from your AI agent to a destination number. The AI agent will handle the conversation according to its configured system prompt and capabilities.

**Required Fields:**
- `destinationNumber`: Phone number to call in E.164 format (e.g., +306912345678)
- `agentId`: ID of the AI agent that will handle the call
- `sipTrunkId`: SIP trunk to dial out from (get from POST /phones/sip-trunks/query)

**Optional Features:**
- `contextForAi`: Additional context appended to the agent's system prompt for this specific call (e.g., customer details, call purpose)
- `dynamicVariables`: Key-value pairs accessible to the agent during the call (e.g., customer name, order ID)
- `callerId`: Override the caller ID shown to the recipient
- `scheduledAt`: Schedule the call for a future date/time instead of immediate execution
- `maxRetries`: Total dial attempts including the first call (0-3, default: 3). 0 or 1 = no automatic retries
- `retryDelayMinutes`: Minutes between those calls (30-1440, default 30). A retry follows a busy line, no answer, voicemail or a failed call

**Protection Settings:**
- `useAntiHarassmentProtection`: (default: true) Prevents excessive outbound calling with daily limits and cooldown periods. Set false to skip.
- `overrideTimeRestriction`: (default: false) Bypass 9 AM - 9 PM local time restrictions
- `overrideDayRestriction`: (default: false) Bypass weekend/holiday restrictions

**Response:**
- `callId`: Unique identifier for tracking this call
- `scheduled`: True if call was scheduled for later due to time restrictions
- `scheduleTime`: The date/time when the call is scheduled (if scheduled)
- `error`: Error code if call initiation failed
- `reason`: Human-readable message explaining the error or scheduling reason

**HTTP Status Codes:**
- `200 OK`: Call initiated successfully or scheduled for later
- `400 Bad Request`: Validation errors (fix the request)
- `402 Payment Required`: Billing/subscription issues (upgrade plan or add credits)
- `403 Forbidden`: `callee_opted_out` - permanent, never retry
- `409 Conflict`: `call_already_in_progress` - a call to this number is already live or scheduled
- `429 Too Many Requests`: anti-harassment limits - retry after `Retry-After`
- `500 Internal Server Error`: Server-side issues (retry later or contact support)

**Refusals and retry semantics:** every refusal has `details.retryable`. When it is true, `details.retryAfterSeconds` (also sent as the `Retry-After` header) and usually `details.nextAllowedAt` say when a retry can succeed. Do not retry sooner, and never retry when `retryable` is false: re-submitting the same call in a loop only repeats the refusal.
- `callee_opted_out` (403) - The callee asked to never be called again. Permanent (`retryable: false`, `permanent: true`): remove the number from your list.
- `call_already_in_progress` (409) - Only one outbound call per number at a time. `details.liveCallId` / `liveCallStatus` identify the call that is already live or scheduled: follow that call instead of re-submitting. When it is scheduled (`alreadyScheduled: true`, `scheduledAt`, `retryable: false`) your request is already covered: mark the number as done on your side, because that call is placed automatically and any re-submission is refused again. Also returned for an identical request (same number + agent) within 60s.
- `daily_call_limit_reached` (429) - Anti-harassment: max 3 outbound calls per number per day. `nextAllowedAt` is the start of the next day (UTC).
- `failed_call_limit_reached` (429) - Max 3 failed attempts per number per day. Retry the next day.
- `cooldown_period_active` (429) - Anti-harassment: 1 hour between connected outbound calls to the same number. `nextAllowedAt` is the last call + 1 hour.

**Validation (400 - fix the request):**
- `agent_not_found` - Invalid agent ID. Check agent exists and is accessible.
- SIP trunk not found or offline. Check `sipTrunkId` and trunk status.
- `distributor_not_found` - Configuration issue. Contact support.

**Billing Issues (402 - Upgrade plan or add credits):**
- `insufficient_credits` - No credits/minutes in plan. Add credits or upgrade.
- `no_seconds_available` - No seconds remaining. Upgrade plan.
- `no_channels_available` - Channel limit reached in plan. Upgrade plan.
- `no_concurrent_calls_available` - All concurrent slots in use. Upgrade plan or wait.

**Server Issues (500 - Retry or contact support):**
- `internal_error` - Unexpected server error. Retry or contact support.
- `server_unavailable` - Calls server unavailable. Retry in a few minutes.

**Note:** All error responses include both `error` (code) and `reason` (detailed message) fields.

**For detailed examples and use cases, see:** https://docs.voicelogica.ai/outbound-calls/api

## Headers

- `x-api-key` string, required
- `x-company-id` string

## Request body

- object: Schema for API call request
  - `sipTrunkId` string, required: SIP trunk to dial out from. Get this from POST /phones/sip-trunks/query.
  - `callerId` string: The phone number or SIP URI shown to the recipient as the caller. When set, this overrides the SIP trunk default caller ID. Use a full E.164 phone number (e.g. "+302101234567") or a SIP identity (e.g. "sip:user@domain.com"). If omitted, the trunk's own caller ID is used.
  - `outBoundCallerIdPrefix` string: Outbound caller ID prefix — determines which phone number we dial out from
  - `destinationNumber` string, required: Destination phone number
  - `isInternalCall` boolean: Whether this is an internal call to an extension (no AI agent needed)
  - `agentId` string: Agent identifier. Required for outbound AI calls, optional for internal extension calls.
  - `contextForAi` string: Additional context information for the AI agent. This text will be appended to the agent's system prompt for this specific call. Typically contains information about the client/customer, their situation, history, preferences, or any relevant details that will help the AI agent personalize the conversation. Example: "Customer John Doe has an outstanding invoice of $500 from last month. He previously mentioned preferring payment via bank transfer."
  - `emailAddress` string: Email address
  - `dynamicVariables` object: Dynamic variables for the call
  - `superVariables` object: Super variables for the call
  - `metadata` object: Additional metadata
  - `overrideTimeRestriction` boolean: Whether to override time restrictions. Time restrictions block calls between 21:00-09:00 local time in the destination country. Set to true to bypass these restrictions.
  - `overrideDayRestriction` boolean: Whether to override day restrictions. Day restrictions may block calls on weekends or specific days based on the destination country regulations. Set to true to bypass these restrictions.
  - `useAntiHarassmentProtection` boolean: Whether to use anti-harassment protections. When enabled (default), enforces: (1) Max 3 successful outbound calls per number per day, (2) Max 3 failed outbound calls per number per day, (3) 1-hour cooldown between successful outbound calls, (4) No duplicate active/scheduled outbound calls. Inbound calls do not count. Numbers in campaign allowlist bypass all protections. Set to false to disable these protections.
  - `isWelcomeMessageAIGenerated` boolean: Whether to use AI generated welcome message
  - `scheduledAt` string, date-time: ISO 8601 date string
  - `retryDelayMinutes` number: Delay between retry attempts in minutes (minimum 30, maximum 1440, default 30). Works in conjunction with maxRetries. If the call fails (busy, missed, voicemail, no answer), the system will wait this many minutes before the next retry attempt. Example: 120 minutes = 2 hours between retries. Default behavior applies if not specified.
  - `maxRetries` number: Maximum number of dial attempts in total, including the first call (0–3, default 3). If the call fails (recipient busy, voicemail, no answer, missed), the system dials again until this many attempts were made. Each retry is delayed by retryDelayMinutes. Example: maxRetries=3 means the first call plus up to 2 retries. 0 or 1 means no automatic retries: send it when your own system handles retries. A callback the recipient asks for during the call is still scheduled.
  - `additionalPhoneNumbers` union, required: Additional phone numbers to call. Accepts a number, a string, or an array. Values may be comma- or space-separated; non-digit characters are stripped automatically.
    - string
    - number
    - union[]
      - union
        - string
        - number

## Response `200`

Call initiated successfully or scheduled

- object: Successful call initiation response (200 OK)
  - `callId` string: Call identifier if call was initiated successfully
  - `scheduled` boolean: Whether the call was scheduled for later due to time/day restrictions
  - `scheduleTime` string, date-time: ISO 8601 date string
  - `reason` string: Explanation for scheduling. Only present when call is scheduled, explains why it was scheduled (e.g., "scheduled due to time restrictions").

## Other responses

- `400`: Bad Request - Validation error
- `401`: Unauthorized
- `402`: Payment Required - Insufficient credits, minutes, or channels
- `403`: Invalid CSRF
- `409`: Conflict - call_already_in_progress: a call to this number is already live or scheduled (details.liveCallId)
- `429`: Rate limit exceeded
- `500`: Internal Server Error

---

[API](https://skmtc.dev/voicelogica/apis/voice-logica-api.md) · [All operations](https://skmtc.dev/voicelogica/apis/voice-logica-api/llms.txt) · [OpenAPI document](https://skmtc.dev/voicelogica/apis/voice-logica-api/revisions/30f76840084e?raw)
