# Build a Lookalike Model


A Lookalike Model learns the behavior of a completed **seed audience** and
produces a new audience of similar devices at the size you ask for. This guide
runs the full journey: pick a seed, create the model, poll it to Completed, then
activate the result. Every field value comes from an endpoint - fetch it there
rather than guessing.

{{< callout type="warning" >}}
**Lookalike Models are a gated feature.** They require additional permissions
which need to be approved by your Account Manager. Without the capability the
create is rejected with `403`.
{{< /callout >}}

## The journey

```
1. List audiences          -> choose a Completed, non-lookalike seed (1,000+ devices)
2. POST .../create-lookalike -> 201, returns the new result-audience id
3. GET  .../audiences/{id}   -> poll 108 Modeling until 104 Completed
4. Activate the result       -> deliver it (1,000-device floor for lookalikes)
```

Each step is asynchronous - see [The Async Model](/concepts/async-model).

## Prerequisites

- A bearer token ([Authentication](/getting-started/authentication)).
- The Lookalike Models capability enabled on your account (see the note above).
- A seed audience that is already **Completed**.

## Step 1 - Pick a seed audience

The seed is any completed audience your company owns. List your audiences and
choose one that satisfies all three seed rules:

- lifecycle status `104` Completed (`status.id`),
- **not** itself a lookalike (`is_lookalike` is `false`), and
- at least **1,000 devices** (`results_count` >= 1000) by default.

```bash
curl "https://console.intuizi.com/api/v2/analyses/audiences/index?per_page=25" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Accept: application/json"
```

Each item in the response carries `status`, `is_lookalike`, and `results_count`
so you can screen candidates directly. The full read is documented at
[List Audiences](/api/v2/audiences/#get-apiv2analysesaudiencesindex); to inspect
one candidate in detail see [Read an Audience](/guides/read-an-audience).

## Step 2 - Create the Lookalike Model

Point the create at your seed's id and supply the model `config`. The complete,
field-level contract - `target_size`, the `geo` scope, the `signals` families
the model learns from (`poi`, `apps`, `demographics`, `transactions`,
`profile_attributes`; `web` and `ctv` are withdrawn), seed-device
exclusion, an optional contrast
audience, and identifier expansion - is on
[Create Lookalike Audience](/api/v2/audiences/#post-apiv2analysesaudiencescreate-lookalike).
Fetch any catalog values (for example the `geo.countries`) from the reference
reads under [Working with Reference Data](/guides/working-with-reference-data)
rather than hardcoding them.

```bash
curl -X POST "https://console.intuizi.com/api/v2/analyses/audiences/create-lookalike" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: <UNIQUE_KEY>" \
  -d '{
    "name": "Coffee Buyers - Lookalike",
    "source_audience_id": 88,
    "config": {
      "target_size": 100000,
      "geo": { "countries": ["USA"], "states": [] },
      "signals": ["poi", "apps", "demographics"],
      "exclude_seed_devices": true,
      "contrast_audience_id": null,
      "expand_eids": false
    }
  }'
```

The response returns the new **result audience** in status `100` Initiating with
`is_lookalike: true`. Capture its `id` - that is what you poll.

{{< callout type="info" >}}
The `Idempotency-Key` header is optional and you generate it yourself, one per
logical create. Reuse it only when retrying the exact same request: the retry
replays the original response instead of launching a second model run. See
[Idempotency](/concepts/idempotency).
{{< /callout >}}

## Step 3 - Poll until Completed

Poll the result audience by id until it finishes. A Lookalike Model spends its
working time in status `108` Modeling; keep polling until it reaches `104`
Completed.

```bash
curl "https://console.intuizi.com/api/v2/analyses/audiences/<LOOKALIKE_ID>" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Accept: application/json"
```

- `100`-`103`, `105`, `108` Modeling, `109` - still working. Poll again
  shortly.
- `104` Completed - the lookalike audience is ready.
- `107` Additional Info - the build stopped and will not continue. Stop
  polling. Audience Manager shows the reason on the audience.
- `4xx` - an error state, including the `400` a run you cancel ends at (see
  [Cancel an in-flight run](#cancel-an-in-flight-run)). Stop polling and
  inspect the response.

See [Polling and Rate Limits](/guides/polling-and-rate-limits) for recommended
intervals and how to handle a `429`.

## Step 4 - Activate the result

A completed lookalike audience activates exactly like any other audience - see
[Activate an Audience](/guides/activate-an-audience) for the full flow.

{{< callout type="warning" >}}
Lookalike audiences carry a higher activation floor: a lookalike must hold at
least **1,000 unique devices** to be activated (ordinary audiences activate from
500) - one of several gates the eligibility engine checks (device floor,
Affinity SCID coverage, retention). The audience read's `is_activation_allowed`
boolean reflects the combined verdict, and `eligibility.reasons[]` names the
specific gate when it is `false` - check it before you activate.
{{< /callout >}}

## Cancel an in-flight run

If you no longer need a model that is still running, request cancellation. This
is cooperative: the run stops at its next checkpoint rather than being killed
instantly, and a run that has already finished cannot be cancelled. Until that
checkpoint the audience keeps reading `108` Modeling. Once the run stops it
ends at `400` Error, which is final, and an `audience.failed`
[webhook](/concepts/webhooks) is sent. Audience Manager shows the status as
`Cancelled on request.` A cancel that arrives once the result is already being
published is ignored, and the run completes at `104`.

```bash
curl -X POST "https://console.intuizi.com/api/v2/analyses/audiences/cancel-lookalike" \
  -H "Authorization: Bearer <YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{ "id": <LOOKALIKE_ID> }'
```

The full contract is at
[Cancel Lookalike](/api/v2/audiences/#post-apiv2analysesaudiencescancel-lookalike).

## Reference

- Field-level contract: [API Reference - Audiences]({{< relref "/api/v2/audiences" >}})
- Concept: [The Async Model](/concepts/async-model)
- Retries and limits: [Polling and Rate Limits](/guides/polling-and-rate-limits)
