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

# Dial-only phone numbers

> Upload contacts with a reference ID instead of a phone number. A pre-conversation action fetches the real number from your system before each call, and Callers keeps only the reference ID.

Some teams can't share their customers' phone numbers ahead of time, for example healthcare providers calling patients. With dial-only phone numbers, you upload each contact with a **reference ID** in place of the phone number. Right before each call, a [pre-conversation action](https://docs.callers.ai/documentation/build-your-agent/agent-actions.md#pre-conversation-actions) asks your system for the real number, and the agent dials it.

The real number is used only to place the call. The contact, the call record, and analytics keep the reference ID.

## When to use it

* Your policies don't allow you to send customer phone numbers to a third party in advance.
* Your own system is the source of truth for phone numbers, and you want every call to use the latest number on file.
* You want call outcomes in Callers linked to an ID you can match in your system, without the phone number attached.

If you can share phone numbers, upload them as usual. See [Add contacts](https://docs.callers.ai/documentation/using-callers/uploading-contacts.md).

## How it works

**1. You upload contacts with reference IDs**

Each contact's `phoneNumber` holds a unique reference ID written in phone number format, such as `+1 212 200 0001`.

**2. Callers asks your system for the number**

Before each call attempt, the pre-conversation action sends the reference ID to your lookup endpoint.

**3. Your system returns the real number**

Callers converts it to international format and checks that it's a valid number.

**4. The agent dials the real number**

The conversation runs as usual. If no valid number comes back, the call isn't placed and the reference ID is never dialed.

**5. Results are stored under the reference ID**

The contact, call record, analytics, and webhooks show the reference ID. A post-conversation webhook can send the outcome back to your system.

## What your endpoint needs

Before you set up the agent, make sure you have a lookup endpoint that:

* Accepts the reference ID, in the URL path or as a query parameter. Callers stores phone numbers as digits only, so a reference ID uploaded as `+1 212 200 0001` arrives as `12122000001`.
* Returns the contact's phone number in a JSON response, for example `{ "phoneNumber": "+14155552671" }`.
* Returns the number in international format with the country code (`+14155552671`). A number in national format (`(415) 555-2671`) also works when it's in the same country as the reference ID.
* Returns a 4xx or 5xx status when it can't find a number, so the call can be stopped cleanly.
* Responds within 5 seconds, the timeout for pre-conversation actions.
* Is reachable over HTTPS from the [Callers IP addresses](https://docs.callers.ai/documentation/build-your-agent/agent-actions.md#ip-allowlist). To confirm that requests come from Callers, [validate the signature](https://docs.callers.ai/documentation/webhook/validating-webhook-signatures.md) on each request.

## Set it up

### 1. Upload contacts with reference IDs

Upload contacts as described in [Add contacts](https://docs.callers.ai/documentation/using-callers/uploading-contacts.md), with a reference ID in the `phoneNumber` column:

* **Unique per contact.** Contacts with the same phone number are merged, so two contacts that share a reference ID would become one.
* **In a valid phone number format.** The import checks the format of every number. An easy way to get valid, unique IDs is to count up within one area code: `+1 212 200 0000`, `+1 212 200 0001`, and so on.
* **In the right country and time zone.** Callers works out each contact's country and time zone from the number in `phoneNumber`. The country is used to read national-format numbers your endpoint returns, and the time zone sets calling hours when the agent uses [Use Contact's Time Zone](https://docs.callers.ai/documentation/contacts/scheduling-and-retries.md#time-zones). Pick reference IDs from an area code in your contacts' time zone, or see the options below.

```csv contacts.csv theme={"dark"}
name,phoneNumber,appointmentDate
Patient 0001,+1 212 200 0001,2026-11-18
Patient 0002,+1 212 200 0002,2026-11-19
```

> [!NOTE]
>
> A `timezone` column in a CSV file isn't used for scheduling. If your contacts are spread over several time zones, add them through the API and send the `timezone` field with an IANA name such as `America/New_York`, or turn off **Use Contact's Time Zone** and set one time zone for the agent. See [Time zones](https://docs.callers.ai/documentation/using-callers/uploading-contacts.md#time-zones).

> [accordion] Reference IDs that aren't valid phone numbers
>
> If your IDs can't be written as valid phone numbers, add contacts one at a time through the API with `ignorePhoneNumberValidation=true`. See [Manage contacts](https://docs.callers.ai/api-reference/guides/manage-contacts.md). The ID must still be 7 to 20 characters of digits, `+`, `(`, `)`, and `-`. Callers can't work out a country or time zone from such an ID, so send `timezone` with each contact, and have your endpoint return numbers in international format with the country code.

### 2. Create the lookup action

**1. Open the agent's workflow**

Go to **Agents**, select the agent, click **Edit**, and open the **Workflow** tab.

**2. Add a pre-conversation action**

Click **+** on **Pre-Conversation Actions**, then click **Create Custom Pre-conversation action**.

**3. Configure the request**

Set **Method** to **GET** and enter your lookup URL. Insert the reference ID with the `{{contact.phoneNumber}}` variable, for example:

```text theme={"dark"}
https://api.example.com/contacts/{{contact.phoneNumber}}/phone
```

Add any **Headers** your API needs, such as `Authorization`.

![Custom pre-conversation action with method GET and a URL that contains the contact phone number variable](https://mintcdn.com/voxiaai/KKsJIyzNaFu_0Nwj/images/documentation/security/dial-only-lookup-request.png?fit=max\&auto=format\&n=KKsJIyzNaFu_0Nwj\&q=85\&s=ea965dc1adbebc6be64a7564dcdcc97a)

Lookup request with the reference ID in the URL

**4. Test the request**

Click **Send Test Request** and enter a reference ID that exists in your system. Check that the response on the right contains the real number.

**5. Map the number to phoneNumber**

Click **Map Contact Info Fields**. Next to **phoneNumber**, click **Choose** and pick the response field that holds the real number. Click **Done**.

### 3. Turn on dial-only mode

On the **Workflow** tab, click the **Pre-Conversation Actions** box to open its settings, and set the action as follows:

| Setting | Value | Why |
| - | - | - |
| **Perform action** | **Before every call** | The number is fetched again for every attempt, including retries. |
| **Update contact data** | Off | The real number isn't saved to the contact. |
| **Don't store on call record** | On | The real number isn't saved on the call record. |
| **Prevent call on unsuccessful response** | On (recommended) | If your endpoint returns a 4xx or 5xx status, the contact is skipped. |

![Pre-Call Actions panel with Before every call, Update contact data off, and Don't store on call record on](https://mintcdn.com/voxiaai/KKsJIyzNaFu_0Nwj/images/documentation/security/dial-only-precall-settings.png?fit=max\&auto=format\&n=KKsJIyzNaFu_0Nwj\&q=85\&s=ec7f5ef54aa09557578da9cab9abfdd8)

Pre-Conversation Actions settings for dial-only mode

Dial-only mode applies only when the first three settings are all set as shown. Save the agent, and **Publish** it if your account uses [versions](https://docs.callers.ai/documentation/build-your-agent/versions-and-split-traffic.md).

> [!WARNING]
>
> If any of the first three settings is different, the action works as a regular pre-conversation action: the returned number is still dialed, but it can be saved to the contact or the call record. Check the settings before you start the agent.

### 4. Send results back to your system (optional)

To receive each outcome under the reference ID, add a post-conversation webhook:

1. On the **Workflow** tab, click **+** on **Post-Conversation Actions** and click **Create Custom Webhook**.

2. Set the method to **POST**, enter your endpoint URL, and build a body with the reference ID and the outcome, for example:

   ```json theme={"dark"}
   {
     "referenceId": "<<contact.phoneNumber>>",
     "callId": "<<id>>",
     "status": "<<status>>",
     "outcome": "<<successCriteria.name>>"
   }
   ```

3. Choose the events that send the webhook and save.

![Custom webhook form with method POST and an example outcome URL](https://mintcdn.com/voxiaai/KKsJIyzNaFu_0Nwj/images/documentation/security/dial-only-outcome-webhook.png?fit=max\&auto=format\&n=KKsJIyzNaFu_0Nwj\&q=85\&s=2e70e86ce26f0f1533104255c7335d11)

Custom webhook that sends the outcome to your system

See [Advanced webhooks](https://docs.callers.ai/documentation/webhook/advanced-webhook.md) for the full template syntax.

## Behavior and edge cases

* **Number format.** Callers converts the returned number to international (E.164) format, using the country of the contact's reference ID for national-format numbers. A value that isn't a valid phone number is dropped.
* **No valid number.** If the lookup fails or returns no valid number, the call isn't placed and the contact is skipped. The reason shows as **Call was not placed because it did not pass pre-call checks**. The reference ID is never dialed.
* **Retries.** Every call attempt runs the lookup again, so a retry always uses the number your system returns at that moment.
* **Other pre-conversation actions.** You can add more pre-conversation actions to the same agent. If another action on the same agent also maps **phoneNumber** without the dial-only settings above, so that the number could be stored, dial-only mode doesn't apply.
* **Duplicates.** Re-importing a contact with the same reference ID updates the existing contact instead of creating a new one.

## What is stored

| | Reference ID | Real phone number |
| - | - | - |
| Contact | Stored | Not stored |
| Call record | Stored | Not stored |
| Analytics and exports | Stored | Not stored |
| Webhooks and actions (`<<contact.phoneNumber>>`, `phoneTo`) | Sent | Not sent |
| Your account's Do Not Call list | Used | Checked before each call, not stored |

The real number is used only to place the call.

## Related settings

These settings aren't required for dial-only mode, but they help keep the data you store to a minimum.

* **Sensitive data detection.** Under the agent's **General Settings** → **Technical Settings**, open the **Sensitive Data** section and turn on **Sensitive data detection**. Under **What counts as sensitive**, select **Personal identifiers** and **Health information** along with **Payment and credentials**. Under **When sensitive data is detected**, choose **Mask sensitive messages**, or **Delete transcripts with sensitive data** and **Delete recordings with sensitive data**. With a mask or delete option on, personal identifiers and health information are then also kept out of contact memories. See [Sensitive data](https://docs.callers.ai/documentation/security/sensitive-data.md).
* **Record Calls.** If you don't need recordings, turn off **Record Calls** in **Technical Settings**. See [Call recording](https://docs.callers.ai/documentation/voice/call-recording-and-limits.md#call-recording).
* **Retention period.** Choose how long recordings and transcripts are kept: click your name at the bottom left, then **Settings** → **General** → **Retention period**. See [Data retention](https://docs.callers.ai/documentation/security/data-access-and-retention.md#data-retention).
* **Do Not Call checks.** Keep **Enable Account Do Not Call (DNC) List** on. When a contact asks not to be called, their reference ID is added to the list, and both the reference ID and the real number are checked before each call. The **US Federal** and **State** registry checks are done through an external provider, which receives the real number before each call. For dial-only agents you may choose to turn them off. If you do, you're responsible for making sure that every person you call may be contacted. See [Do Not Call](https://docs.callers.ai/documentation/contacts/do-not-call.md).

## Troubleshooting

> [accordion] A contact was skipped with "Call was not placed because it did not pass pre-call checks"
>
> The lookup returned a 4xx or 5xx status, or its response didn't contain a valid phone number. Check your endpoint's logs for the request with that reference ID, and run **Send Test Request** on the action with the same ID. Make sure the reference ID exists in your system, that the field mapped to **phoneNumber** holds the number, and that national-format numbers are in the same country as the reference ID.

> [accordion] The call dialed the right number, but I see a different number in Callers
>
> That's expected. Callers shows the reference ID you uploaded everywhere. The real number is used only to place the call.

> [accordion] Does a retry use the same number?
>
> Each retry runs the lookup again and dials the number your system returns at that time. If the number changed in your system between attempts, the retry uses the new one.

> [accordion] The real number was saved to the contact
>
> Dial-only mode isn't on. Check that **Perform action** is **Before every call**, **Update contact data** is off, and **Don't store on call record** is on, and that no other pre-conversation action on the agent maps and stores **phoneNumber**.

> [accordion] Some rows failed with an invalid phone number
>
> The reference IDs must be in a valid phone number format. Count up within one area code, or add contacts through the API with `ignorePhoneNumberValidation=true`.

> [accordion] Calls happen at the wrong local time
>
> Calling hours follow the time zone of the reference ID, not of the real number. Use reference IDs from an area code in your contacts' time zone, send `timezone` through the API, or set one time zone for the agent. See [Scheduling and retries](https://docs.callers.ai/documentation/contacts/scheduling-and-retries.md#time-zones).

## Related

> [card] [Actions](https://docs.callers.ai/documentation/build-your-agent/agent-actions.md#pre-conversation-actions)
>
> Pre-conversation actions, settings, and the request your endpoint receives.

> [card] [Add contacts](https://docs.callers.ai/documentation/using-callers/uploading-contacts.md)
>
> CSV format, time zones, and the contacts API.

> [card] [Sensitive data](https://docs.callers.ai/documentation/security/sensitive-data.md)
>
> Choose what counts as sensitive, and mask or delete it.

> [card] [Security overview](https://docs.callers.ai/documentation/security/overview.md)
>
> Every security control in one place.

> [card] [Advanced webhooks](https://docs.callers.ai/documentation/webhook/advanced-webhook.md)
>
> Send outcomes back to your system.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.