> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselevers.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Call single phone number

> Learn how to initiate an AI-powered phone call to a single number

## Trigger AI Phone Call

Initiate an AI-powered phone call by providing a phone number.

<Note>
  The API automatically creates a contact record if one doesn't exist, or you can reference an existing contact.
</Note>

<CodeGroup>
  ```bash request.sh theme={null}
  # Basic call - phone number only
  # (auto-creates contact with only the phone number)
  curl --request POST \
  --url https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "numberToCall": "+96612341234",
    "metadata": {
      "project_id": "proj_123",
      "extra_id": "custom_id_456"
    }
  }'

  # With contact details (auto-creates contact with more information)
  curl --request POST \
  --url https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "numberToCall": "+96612341234",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "metadata": {
      "project_id": "proj_123",
      "extra_id": "custom_id_456"
    }
  }'

  # Update existing contact details if found
  curl --request POST \
  --url https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "numberToCall": "+96612341234",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "updateExisting": true,
    "metadata": {
      "project_id": "proj_123",
      "extra_id": "custom_id_456"
    }
  }'

  # Link to an existing contact by UUID
  curl --request POST \
  --url https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "numberToCall": "+96612341234",
    "contactUuid": "9bfa828a-3c2d-430c-bdc7-f74d90334524",
    "metadata": {
      "project_id": "proj_123",
      "extra_id": "custom_id_456"
    }
  }'

  # With custom AI settings template
  curl --request POST \
  --url https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "numberToCall": "+96612341234",
    "firstName": "John",
    "lastName": "Doe",
    "aiSettingsTemplateId": "template-uuid-here",
    "metadata": {
      "project_id": "proj_123",
      "extra_id": "custom_id_456"
    }
  }'

  # With prompt tags for template variable substitution
  curl --request POST \
  --url https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "numberToCall": "+96612341234",
    "firstName": "John",
    "aiSettingsTemplateId": "template-uuid-here",
    "promptTags": {
      "amount": "$500.00",
      "due_date": "January 15, 2026"
    }
  }'
  ```

  ```python request.py theme={null}
  import requests

  url = "https://api.dev.uselevers.com/api-service/v1/ai/phone-calls/action/call"
  headers = {"Authorization": "Bearer <token>"}

  # Basic call - phone number only (auto-creates contact with only the phone number)
  data = {
    "numberToCall": "+96612341234",
    "metadata": {
        "project_id": "proj_123",
        "extra_id": "custom_id_456"
    }
  }
  response = requests.post(url, json=data, headers=headers)
  print(response.text)

  # With contact details (auto-creates contact with more information)
  data = {
    "numberToCall": "+96612341234",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "metadata": {
        "project_id": "proj_123",
        "extra_id": "custom_id_456"
    }
  }
  response = requests.post(url, json=data, headers=headers)
  print(response.text)

  # Update existing contact details if found
  data = {
    "numberToCall": "+96612341234",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "updateExisting": True,
    "metadata": {
        "project_id": "proj_123",
        "extra_id": "custom_id_456"
    }
  }
  response = requests.post(url, json=data, headers=headers)
  print(response.text)

  # Link to an existing contact by UUID
  data = {
    "numberToCall": "+96612341234",
    "contactUuid": "9bfa828a-3c2d-430c-bdc7-f74d90334524",
    "metadata": {
        "project_id": "proj_123",
        "extra_id": "custom_id_456"
    }
  }
  response = requests.post(url, json=data, headers=headers)
  print(response.text)

  # With custom AI settings template
  data = {
    "numberToCall": "+96612341234",
    "firstName": "John",
    "lastName": "Doe",
    "aiSettingsTemplateId": "template-uuid-here",
    "metadata": {
        "project_id": "proj_123",
        "extra_id": "custom_id_456"
    }
  }
  response = requests.post(url, json=data, headers=headers)
  print(response.text)

  # With prompt tags for template variable substitution
  data = {
    "numberToCall": "+96612341234",
    "firstName": "John",
    "aiSettingsTemplateId": "template-uuid-here",
    "promptTags": {
        "amount": "$500.00",
        "due_date": "January 15, 2026"
    }
  }
  response = requests.post(url, json=data, headers=headers)
  print(response.text)
  ```
</CodeGroup>

### Request Fields

<ResponseField name="numberToCall" type="string" required>
  Phone number to call. We automatically search for any existing contact with this number to avoid creating duplicates.
</ResponseField>

<ResponseField name="firstName" type="string">
  Contact's first name (used when creating or updating the contact)
</ResponseField>

<ResponseField name="lastName" type="string">
  Contact's last name (used when creating or updating the contact)
</ResponseField>

<ResponseField name="email" type="string">
  Contact's email address (used when creating or updating the contact)
</ResponseField>

<ResponseField name="contactUuid" type="string (UUID)">
  Explicitly link the call to a specific contact. This is useful when calling a contact at a different number than their default one—the `numberToCall` is still dialed, but the call is associated with the specified contact. If the UUID doesn't exist, we'll fall back to searching by phone number and create a new contact.
</ResponseField>

<ResponseField name="aiSettingsTemplateId" type="string (UUID)">
  Customize how the AI behaves during the call using your prompt templates from the Levers app. If not specified, the default template will be used.
</ResponseField>

<ResponseField name="metadata" type="object">
  Optional field for sending extra payload data with the call. This metadata will be included in webhook responses as `requestMetadata`, allowing you to track additional context like `project_id`, `extra_id`, or any custom key-value pairs relevant to your application.

  <Expandable title="Example" defaultOpen>
    ```json theme={null}
    {
      "project_id": "proj_123",
      "extra_id": "custom_id_456"
    }
    ```
  </Expandable>
</ResponseField>

<ResponseField name="promptTags" type="object">
  Optional key-value pairs for template variable substitution in the system prompt. Each key maps to a placeholder in your prompt template (e.g., \{\{amount}}), and the value replaces it before the call starts. Only string values are supported.

  This is separate from `metadata` — `metadata` is stored on the call log and included in webhooks, while `promptTags` is consumed at call time to populate the system prompt.

  <>
    <Expandable title="How template substitution works" defaultOpen>
      Your system prompt template uses double-curly-brace placeholders (e.g., \{\{amount}}):

      ```plain theme={null}
      You are a collections agent. The customer owes {{amount}} due by {{due_date}}.
      Be professional and offer payment plan options if the customer cannot pay in full.
      ```

      With this request:

      ```json theme={null}
      {
        "promptTags": {
          "amount": "$500.00",
          "due_date": "January 15, 2026"
        }
      }
      ```

      The AI receives:

      ```plain theme={null}
      You are a collections agent. The customer owes $500.00 due by January 15, 2026.
      Be professional and offer payment plan options if the customer cannot pay in full.
      ```
    </Expandable>

    <Expandable title="Using promptTags for guardrails">
      You can also inject additional instructions dynamically:

      ```json theme={null}
      {
        "promptTags": {
          "amount": "$1,200.00",
          "due_date": "February 1, 2026",
          "guardrail": "Do not mention late fees. If the customer asks about penalties, redirect to their account portal."
        }
      }
      ```
    </Expandable>
  </>
</ResponseField>

<ResponseField name="updateExisting" type="boolean" default="false">
  When `true`, if an existing contact is found with the provided `numberToCall`, their `firstName`, `lastName`, and `email` will be updated with the provided values. If no contact is found with that phone number, a new contact will be created with the provided details.
</ResponseField>
