# Set up Contact Synchronization from Microsoft SQL

Once Cloud Voice is connected to your Microsoft SQL database, you can pull contact records into the system on a set schedule. Imported contacts become dialable from the Cloud Voice App, and because each batch lands in a phonebook, you can also route incoming calls to the right team by matching a caller against a particular phonebook.

## Capacity limits

How many company contacts and phonebooks your system can hold depends on the number of extensions it has.

| Extensions (N) | N ≤ 50 | 50 < N ≤ 200 | N > 200 |
| --- | --- | --- | --- |
| Company contacts (total) | 50,000 | 200,000 | 500,000 |
| Company phonebooks | 100 | 200 | 500 |

## Before you begin

Map the contact fields you want to exchange between Cloud Voice and Microsoft SQL. See [Integrate Cloud Voice with Microsoft SQL](/pbx/integrations/microsoft-sql/integrate-cloud-voice-cloud-voice-with-microsoft-sql/#step-2-map-fields-between-cloud-voice-and-microsoft-sql).

## Sync contacts from Microsoft SQL

1. On the Microsoft SQL configuration page, scroll down to the **Contacts Synchronization** section.

2. Turn on **Contacts Synchronization**, then complete the settings below.

   
   ![Cloud Voice, contact synchronization options for a Microsoft SQL source](/images/pbx/mysql-contact-sync.png)

   **Synchronize to Phonebook**: Decide where the imported contacts are stored:

   - **Create New**: Build a brand-new phonebook for the synced contacts. Enter its name in the **Phonebook Name** field.
   - **Read Specific Property Value and Create New**: Generate phonebooks automatically from the values held in one column of your contact table. Enter that column's name in the **Property Name** field.

     :::note
     This is useful when you want to route inbound calls to different destinations based on phonebook matches. For example, if a column named `belongto` records the team that owns each contact, `Sales` or `Support`, entering `belongto` in the field creates two phonebooks, **Sales** and **Support**, when you save. You can then build inbound routes that send each caller to the responsible team based on which phonebook they match.
     :::

   - **{existing_phonebook}**: Send the contacts to an existing empty phonebook.

     :::note
     The empty phonebooks offered here are the ones already defined under **Contacts > Phonebooks**.
     :::

   **Data Synchronization Frequency**: Choose how often contacts are synced, then set the time in the field that appears.

   :::note
   Syncing a large number of contacts can affect system performance, so schedule synchronization for off-peak hours.
   :::

   **Feedback Email**: Optional. Enter an address to be notified of each synchronization result.

   :::note
   You can enter up to 5 addresses. Separate them with a semicolon (`;`).
   :::

   **Sync Contact Filter**: Enter the `SELECT` statement that pulls records from Microsoft SQL, using the form `select ${MAP} from {schema_name}.{table_name}`.

   :::note
   The `TOP` clause is not supported.
   :::

   For example: `select ${MAP} from testpbx.contacts order by id desc`

   - **`select ${MAP}`**, the database columns to bring into the system. At runtime, `${MAP}` is replaced by the field values that correspond to the fields you enabled in the [Map section](/pbx/integrations/microsoft-sql/integrate-cloud-voice-cloud-voice-with-microsoft-sql/#step-2-map-fields-between-cloud-voice-and-microsoft-sql).
   - **`from testpbx.contacts`**, the source table, written as a two-part name (`{schema_name}.{table_name}`).
   - **`order by id desc`**, sorts the results in descending order.

   **Remove existing contacts which are not received from the server**: When enabled, any contact that synced successfully last time but is missing from the current run is deleted.

   :::caution
   This setting deletes contacts. If your **Sync Contact Filter** is too narrow, or the database is only partly reachable during a run, valid contacts can be removed because they were not returned that time. Leave this off until you have confirmed your filter returns the full set of records you expect.
   :::

3. Click **Save**.

4. Click **Sync Now** to synchronize contacts right away.

   ![The Sync Now control that triggers an immediate contact import](/images/pbx/mysql-contact-sync-now.png)

## Check the results

- A banner appears showing how many contacts were synchronized into the system.

  ![Success banner reporting the number of contacts imported](/images/pbx/mssql-contact-sync-success.png)

- Review the imported contacts and their phonebooks under **Contacts > Company Contacts / Phonebooks**. Records that came from the SQL source carry a source tag ![Microsoft SQL source tag](/images/pbx/mssql-tag.png).

  ![Imported contacts listed under Company Contacts with their assigned phonebooks](/images/pbx/mssql-contact-sync.png)

- Authorized extension users can view and dial the contacts directly from the Cloud Voice App.

  :::note
  To make this work, grant users viewing permission for the relevant phonebook under **Extension and Trunk > Client Permission > Contact Visibility**, and have them update the Cloud Voice App to at least these versions:

  - iOS: 5.7.3 or later
  - Android: 5.7.4 or later
  - Windows desktop: 1.7.3 or later
  - Mac desktop: 1.7.3 or later
  :::

  ![Client permission setting that lets extension users see and call the synced phonebook](/images/pbx/allow-view-mssql-phonebook.png)

## Next steps

To send incoming calls to specific destinations based on which phonebook a contact belongs to, set up inbound routes that match callers against your phonebooks.
