# Sync Audiences to Facebook Custom Audience


This guide lists the steps to configure Facebook Custom Audience as a destination in RudderStack and sync the created audiences to it.

##  Setup

1. Set up an audience in RudderStack using the [Audience Builder]({{< ref "audiences/audience-builder/create-audience.md" >}}).
2. Go to the **Syncs** tab of the audience page and click **Add sync**. Then, select **Facebook Custom Audience**.
3. Click **New destination** — you can also select an already-configured destination here.
4. Specify a unique name to identify this destination in RudderStack.
5. In the **Event delivery account** section, click **Select** to choose from an existing Facebook Ads account from the list. You can also click **Add account** and authenticate using a Facebook API access token:

| Setting | <div style="width: 350px;">Description</div> |
| :----| :-----|
| Account Name | Specify a unique Custom Audience account name |
| Access Token | Enter the [access token](#where-can-i-find-the-user-access-token-for-the-application) of your business application set up for accessing the Facebook Marketing API |
| App Secret | This field is **optional**. Enter the [app secret](https://developers.facebook.com/docs/facebook-login/security/#appsecret) from the **Basic app settings** page of your [Facebook Developer account](https://developers.facebook.com/) |

6. The **Ad Account ID** field is pre-populated based on the selected Facebook Ads account — select the ID.

## Configure sync

This section lists the settings to correctly configure your audience syncs to the Facebook Custom Audience destination.

{{< info >}}
The following two audience types are supported:

- [Custom Audiences](https://developers.facebook.com/docs/marketing-api/audiences/guides/custom-audiences)
- [Value-based lookalike audiences](https://en-gb.facebook.com/business/help/917879191754763?id=401668390442328) — see [Create new value-based lookalike audiences](#create-new-audience) section for more information.
{{< /info >}}

### Select audience

In this section, you can create a new audience or use an existing one.

- **Create new audience**: Use this option to create a new custom audience in Facebook. You can specify the name and description of the new Facebook audience.

{{< info >}}
If you select **Create new audience**, a new audience is created in Facebook with the same **Ad Account ID** configured in the [connection settings](#setup).
{{< /info >}}

- **Use existing audience**: Select an existing custom audience. This field is populated based on your [connection settings](#setup).

### Sync mode

RudderStack supports only [Mirror mode]({{< ref "data-pipelines/reverse-etl/developer-guides/sync-modes.md#mirror-mode" >}}) for this integration.

### Map identifiers

In this section, you can map your warehouse columns to specific Custom Audience fields that represent your audience's identity.

{{< image src="images/audiences/destinations/fb-custom-audience/map-identifiers-syncs.webp" >}}

### Advanced settings

| Setting | <div style="width: 350px;">Description</div> |
| :----| :-----|
| Automatically hash PII data | When set to **Yes**, user data is hash-encoded irrespective of whether the data is already hashed or not. <br /><br />**Note**:  Facebook expects the user data to be hash encoded using `SHA256`. <br /><br />See [Data hashing](#data-hashing) section for more information. |
| Normalize data formatting | When set to **Yes**, Facebook automatically cleans and standardizes the audience data, like emails and phone numbers. <br /><br />See [Data normalization](#data-normalization) section for more information. |
| Specify where your data originates from | Select the field that describes the origin of your data — this helps Facebook classify the user list and apply matching and privacy rules. | 
| Specify identifier type | Choose the identifier type that Facebook Ads uses to match users to their profiles. | 

## Sync settings

{{< customreadfile "/includes/audiences/sync-settings.md" >}}

## Enable sync

{{< customreadfile "/includes/audiences/enable-sync.md" >}}

## Manage value-based lookalike audiences

This section describes the steps to map your warehouse data to a new or existing value-based lookalike audience.

#### New audience

To create a new [value-based lookalike audience](https://en-gb.facebook.com/business/help/917879191754763?id=401668390442328), map a warehouse column to the **Lookalike Value** field in the [Identifier mappings](#map-identifiers):

1. In the [Select audience](#select-audience) section, select **Create new audience** and specify the audience name and description.
2. In the **Choose identifier mappings** window, map a warehouse column to the **Lookalike Value** field.

{{< info >}}
Note that:

- A value-based lookalike audience is not created if you do not include the **Lookalike Value** in your identifier mappings — a [custom audience](https://developers.facebook.com/docs/marketing-api/audiences/guides/custom-audiences) is created instead.
- You can update the mapping for the **Lookalike Value** field after the audience is created.
{{< /info >}}

{{< image src="images/audiences/destinations/fb-custom-audience/lookalike-value-mapping-new.webp" >}}

4. Set up the other identifier mappings as per your requirement.
5. Continue with the rest of the setup.

#### Existing value-based lookalike audience

1. In the [Select audience](#select-audience) section, select **Use existing audience** and select the value-based lookalike audience from the dropdown.
2. In the **Choose identifier mappings** window, map a warehouse column to the **Lookalike Value** field.

{{< info >}}
You can update the mapping for the **Lookalike Value** field after the audience is created.
{{< /info >}}

3. Set up the other identifier mappings as per your requirement.
4. Continue with the rest of the setup.

{{< warning >}}
You cannot change the audience type from a value-based lookalike audience to a regular custom audience (and vice versa) **after** the audience is created.
{{< /warning >}}

## Schema fields mapping

The following table details the schema field mappings specified in the dashboard:

| Dashboard field name | Marketing API schema field | 
| :-------------- | :------------ | 
| `EMAIL` | `EMAIL` | 
| `PHONE` | `PHONE` |  
| `GENDER` | `GEN` |  
| `MADID` | `MADID` | 
| `EXTERN_ID` | `EXTERN_ID` | 
| `DOB YEAR (YYYY)` | `DOBY` |  
| `DOB MONTH (MM)` | `DOBM` |  
| `DOB DATE (DD)` | `DOBD` |
| `LAST NAME` | `LN` |
| `FIRST NAME` | `FN` |
| `FIRST NAME INITIAL`     | `FI` |
| `CITY` | `CT` |
| `US STATES` | `ST` |
| `ZIP` | `ZIP` |
| `COUNTRY` | `COUNTRY` |

Note that the `MADID` and `EXTERN_ID` fields are not hashed.

{{< warning >}}
RudderStack modifies the schema names visible in the dashboard for readability. However, during the event call, the field names **must be exactly the same as** the schema names specified by Facebook Marketing API, as mentioned in the table above.
{{< /warning >}}

## Data normalization

By default, RudderStack formats the data as prescribed by Facebook before sending it to the destination:

| Schema field name | Example input | Formatted output (before hashing) |
| :----------- | :--------- | :---------------------- |
| `EMAIL` | `ABC@gmail.com`   | `abc@gmail.com` |
| `PHONE` | `0@96346895` | `96346895` |
| `GEN` | `FEMALE` | `f` |
| `DOBD` | `2` | `02` |
| `DOBM` | `1` | `01` |
| `LN & FN` | `Abc,@` | `abc@` |
| `FI` | `Mr.` | `mr.` |
| `CT` | `HN#` | `hn` |
| `ST` | `? AL ?` | `al` |
| `ZIP` | `11502 @bc` | `11502@bc` |
| `COUNTRY` | `IN` | `in` |

If you enable the [Normalize data formatting](#advanced-settings) setting, user data is formatted as prescribed by the Facebook Marketing API.

After normalization, each field is validated before sending it to Facebook. 

- Invalid fields are **not** sent to Facebook.
- If all fields in a row are invalid, then the entire row is rejected and marked as failed

{{< info >}}
Data is first normalized, then validated (skipping invalid rows), then [hashed](#data-hashing) before sending to Facebook.
{{< /info >}}

## Data hashing

The [Automatically hash PII data](#advanced-settings) setting lets you hash your user data before sending it to Facebook. This setting is enabled by default.

- Configure the setting to **Yes** if your incoming data is not pre-hashed
- Configure this setting to **No** if your data is already hashed

{{< warning >}}
Incorrect configuration of the **Automatically hash PII data** setting will result in failures.

- If the **Automatically hash PII data** setting is configured to **Yes** and your data is pre-hashed, the event will fail.
- If the **Automatically hash PII data** setting is configured to **No** and your data is not pre-hashed, the event will fail.
{{< /warning >}}

Such events are rejected with a clear error message, for example:

```text
Hashing is disabled but the value for field EMAIL appears to be unhashed. Either enable hashing or send pre-hashed data.
```

You will also see errors in the **Events** tab for cases that were previously marked as successful but resulted in no matches, helping you identify and fix data quality or configuration issues.

## FAQ

#### Where can I find the Ad Account ID?

Go to your Facebook [Ads Manager account](https://www.facebook.com/adsmanager/manage/) where you can find the Ad Account ID in the account's drop-down menu:

{{< image src="images/event-stream-destinations/ads-account-id-fb.webp" alt="Audience source" >}} 

You can click on **See More Ad Accounts** if the required Ad account is not visible.

#### Where can I find the user Access Token for the application?

{{< warning >}}
To generate the user access token for your application, you must first [add it as a system user asset](#how-do-i-add-an-app-as-a-system-user-asset-with-manage-permissions) with manage permissions.
{{< /warning >}}

Follow these steps to generate a user access token required to use the Facebook Marketing API:

1. Under the system user, click the **Generate New Token** button and select the app from the dropdown.

{{< image src="images/event-stream-destinations/fb-custom-audience-generate-new-token.webp" alt="Generate new token" >}}

{{< image src="images/event-stream-destinations/fb-custom-audience-token-select-app.webp" alt="Select app for the token" >}}

2. Choose the **Token expiration** time.

{{< image src="images/event-stream-destinations/fb-custom-audience-token-settings.webp" alt="Token settings" >}}

3. Under **Available permissions**, select `ads_read` and `ads_management`.

{{< image src="images/event-stream-destinations/fb-custom-audience-available-permissions-1.webp" alt="Token permissions" >}}
{{< image src="images/event-stream-destinations/fb-custom-audience-available-permissions-2.webp" alt="Token permissions" >}}

4. Click the **Generate Token** button and copy the token credentials.

#### Why am I seeing the error “Failed to update the custom audience. Facebook responded with error code: 2650?

This error is not explicitly documented by Facebook but is a known API-level limitation. `Error 2650` typically occurs when attempting to add users to a custom audience that was created using a different data source. 

For example:

- Audience originally created via manual file upload
- Audience created through another platform or integration

{{< info >}}
Facebook does not allow mixing data source types within the same custom audience.
{{< /info >}}

<br />
