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

# Sync audiences

> Sync first-party CRM audiences for an advertiser

`POST /api/v2/buyer/advertisers/{advertiserId}/audiences/sync`

Syncs first-party CRM audiences for an advertiser by adding, removing, or deleting members. Processing is **asynchronous** — the call returns `202` with a `taskId` you poll for completion.

## Request

```bash curl theme={null}
curl -X POST https://api.interchange.io/api/v2/buyer/advertisers/25/audiences/sync \
  -H "Authorization: Bearer $SCOPE3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audiences": [
      {
        "audienceId": "loyalty-members-2026",
        "name": "Loyalty members",
        "consentBasis": "consent",
        "add": [
          { "externalId": "cust_8841", "hashedEmail": "a1b2c3d4e5f6071829304152637485960718293041526374859607182930a1b2" }
        ],
        "remove": [
          { "externalId": "cust_2210" }
        ]
      }
    ],
    "deleteMissing": false
  }'
```

## Parameters

| Field                      | Type          | Required | Notes                                                                                                   |
| -------------------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `advertiserId`             | string (path) | Yes      | Advertiser ID (numeric string, e.g. `25`)                                                               |
| `audiences`                | array         | Yes      | Audiences to sync (at least 1)                                                                          |
| `audiences[].audienceId`   | string        | Yes      | Buyer's identifier for the audience (1–255 chars). Used in targeting overlays                           |
| `audiences[].name`         | string        | No       | Human-readable name (max 255 chars)                                                                     |
| `audiences[].consentBasis` | enum          | No       | GDPR lawful basis: `consent`, `legitimate_interest`, `contract`, `legal_obligation`                     |
| `audiences[].add`          | array         | No       | Members to add (max 100000). Each needs `externalId`; optionally `hashedEmail`, `hashedPhone`, `uids[]` |
| `audiences[].remove`       | array         | No       | Members to remove by `externalId` (max 100000)                                                          |
| `audiences[].delete`       | boolean       | No       | When `true`, delete this audience entirely                                                              |
| `deleteMissing`            | boolean       | No       | When `true`, audiences not in this request are marked deleted                                           |
| `pushNotificationConfig`   | object        | No       | ADCP push notification config to receive a callback when processing completes                           |

<Note>
  `hashedEmail` is the SHA-256 hash of a lowercased, trimmed email (64-char
  hex). `hashedPhone` is the SHA-256 hash of an E.164 phone number. Send hashed
  identifiers, never raw PII.
</Note>

<Note>
  TikTok Customer File audiences require at least 1,000 valid members when the
  audience is first created. TikTok processing is asynchronous and can take up
  to 24–48 hours. TikTok additions and removals must include a SHA-256 email,
  phone, or MAID; `externalId` alone cannot identify a TikTok member. Retry with
  the same audience ID and idempotency key if a create, update, or delete
  response is interrupted. Interchange reuses the provider audience and checks
  TikTok's current state instead of creating a duplicate. An accepted upload
  does not mean matching is finished: wait while the audience is `processing`
  and poll its status until TikTok reports a final result. If a failed create
  cannot be cleaned up immediately, the response tells you to retry the delete;
  Interchange does not report success until TikTok confirms the audience is
  gone.
</Note>

## Response

```json theme={null}
{
  "success": true,
  "accountId": "25",
  "operationId": "550e8400-e29b-41d4-a716-446655440000",
  "taskId": "550e8400-e29b-41d4-a716-446655440000"
}
```

Returns `202 Accepted`. `taskId` (identical to `operationId`) tracks async processing — poll `GET /api/v2/buyer/tasks/{taskId}` until `status` is `completed` or `failed`. See [Async tasks](/v2/guides/tasks). The synced audiences then appear via [List audiences](/v2/buyer/advertisers/tasks/list-audiences).

## Errors

* `400 VALIDATION_ERROR` — empty `audiences`, malformed `hashedEmail`/`hashedPhone`, or a batch exceeding 100000 members.
* `404 NOT_FOUND` — `advertiserId` does not exist or is not visible to the authenticated account.

See [Errors](/v2/reference/errors) for the full error contract.

## Related

<CardGroup cols={2}>
  <Card title="Advertiser tasks" href="/v2/buyer/advertisers/tasks" icon="list-check">
    All advertiser operations
  </Card>

  <Card title="Async tasks" href="/v2/guides/tasks" icon="hourglass-half">
    Poll a taskId to completion
  </Card>

  <Card title="List audiences" href="/v2/buyer/advertisers/tasks/list-audiences" icon="users">
    Check match status after sync
  </Card>

  <Card title="Advertiser overview" href="/v2/object-guides/advertiser" icon="user-tie">
    Fields, lifecycle, and concepts
  </Card>
</CardGroup>
