# Automate with an AI Agent


Everything in these guides can be driven by an AI agent instead of by code. The
[MCP server](/mcp) exposes the API v2 surface - reference lookups, audiences,
activations, cohorts and POI data - as tools an agent can call, and every tool
call behaves exactly like the REST endpoint it wraps: same validation, same
envelope, same rate limits.

This is the journey version of
[MCP > Getting started](/mcp/getting-started): what a complete, well-behaved
agent run looks like from connection to delivered audience.

## 1. Connect the agent

Point your client at `https://console.intuizi.com/api/v2/mcp` (Streamable
HTTP). If it supports OAuth, that URL is all it needs: it sends you to an
Intuizi consent screen and there is no credential to handle. For an unattended
run, mint an MCP token with
[Create MCP Token](/api/v2/authentication#post-apiv2authmcptoken) and send it
as an `Authorization: Bearer` header instead. Ready-made configuration
snippets for both paths are in
[MCP > Getting started](/mcp/getting-started).

A few properties worth knowing before you hand a token to an agent:

- MCP tokens are **long-lived** (one year by default) and are not rotated by
  console logins, so an unattended agent keeps working between sessions.
- The token carries **your account's access**. An agent holding it can do
  anything you can do through the API, including creating live deliveries.
- To disconnect an agent permanently, revoke the tokens with
  [Revoke MCP Tokens](/api/v2/authentication#post-apiv2authmcptokenrevoke).
  Changing your password revokes them too.

## 2. The loop: lookup, create, poll, activate

Every Intuizi journey an agent can run is the same four-beat loop. The tools per
beat, with the endpoint each one wraps, are in the
[Tools reference](/mcp/tools-reference).

| Beat | Tools | What the agent is doing |
| --- | --- | --- |
| **Lookup** | `lookup_reference` | Reading the catalogs to discover real ids and values. |
| **Create** | `create_audience`, `create_cohort`, `create_lookalike_audience` | Submitting the work; the response returns an id immediately. |
| **Poll** | `get_audience`, `get_cohort`, `get_activation` | Waiting for the lifecycle status to reach `104` Completed. |
| **Activate** | `lookup_reference`, then `create_activation` | Resolving the destination, then delivering. |

Three ordering rules make the difference between a run that works and a run that
argues with `422`s:

1. **Never invent an id.** Ids come from `lookup_reference`, from a create
   response, or from a list tool - never from the model's memory. The catalogs
   are specific to your account, so a plausible-looking id is usually a wrong
   one.
2. **Some lookups need a parent value first.** Provider and geo catalogs cascade
   from a chosen dataset type or country, and the pricing and datastream
   catalogs need the `partner_id` of the connection you picked. The tool
   descriptions state each requirement;
   [Working with Reference Data](/guides/working-with-reference-data) is the
   long form.
3. **`104` Completed is the only terminal success state**, and `105`
   DataStreaming happens **before** it. An agent that stops at `105` reports
   success too early.

### What the agent should do at each beat

- **Lookup.** Read the dataset types the account can use, then the catalogs for
  the dataset being targeted. Have the agent show you the shortlisted values
  before it builds anything - see
  [Working with Reference Data](/guides/working-with-reference-data).
- **Create.** Build the audience from those values only, and pass an
  `idempotency_key` (below). See
  [Create an Audience](/guides/create-an-audience).
- **Poll.** Call `get_audience` until `data[0].status.id` is `104`, backing off
  between calls. Then read `results_count` and `is_activation_allowed` (and
  `eligibility.reasons` when it is false - e.g. an Affinity audience needs
  unique EIDs above 2x unique SCIDs; the observed counts are in the reason) - an
  audience under 500 devices cannot be activated, and knowing that before the
  activation attempt saves a wasted write.
- **Activate.** Read `endpoint-connections`, then the pricing models and
  datastreams for that connection's `partner.id`, and send `create_activation`.
  The per-partner details - index-matched inputs, enabling streams,
  service-account keys - are in
  [Deliver to a Partner Endpoint](/guides/deliver-to-a-partner-endpoint). Then
  poll `get_activation` to `104`.

The server also ships a guided prompt, `build_and_activate_audience`, that walks
an agent through exactly this order. Invoking it is the fastest way to get a
correct first run.

## 3. Make every create retryable with `idempotency_key`

An agent retries. A dropped tool call, a `429`, a context reset mid-run - any of
them can leave the agent unsure whether a create actually landed. The create
tools take an `idempotency_key` argument that maps to the `Idempotency-Key`
header, with identical semantics:

- Generate **one key per logical create** (a UUID is typical) and pass it on the
  first attempt.
- **Reuse that same key on every retry** of that same create. If the original
  succeeded, the retry replays the original response instead of creating a
  second resource; if it never ran, the retry executes cleanly.
- **Do not reuse a key for a genuinely new create.** The same key with a
  different body is rejected with `409`.

The tools that accept it are the five creates: `create_audience`,
`create_lookalike_audience`, `create_cohort`, `create_activation` and
`create_project`. Full semantics are on [Idempotency](/concepts/idempotency).

{{< callout type="warning" >}}
`create_activation` is the one to be strict about. An activation is a live,
billable, non-reversible delivery to an external destination, so a duplicated
create is a duplicated delivery. Always pass an `idempotency_key`, and prefer
having the agent confirm the audience, the connection and the pricing model with
you before it calls the tool.
{{< /callout >}}

## 4. Respect the rate limits

Tool calls consume the **same per-token buckets** as direct API calls - an MCP
token is not a separate allowance:

| Bucket | Limit | What counts |
| --- | --- | --- |
| Read | 120 requests/min | `lookup_reference`, every `list_*` and `get_*` tool, and every poll |
| Write | 30 requests/min | Every write tool: the creates, the deletes, and `cancel_lookalike` |
| MCP endpoint | 120 requests/min | Every request to the MCP endpoint itself |

Polling is read traffic, so a tight poll loop is the easiest way for an agent to
exhaust 120 reads/min on its own. Have it poll on a few seconds' interval and
back off as the wait grows (for example 5s, then 10s, then 30s), with an overall
timeout so a stuck job does not poll forever.

On a `429` the tool error text includes the `Retry-After` seconds. The correct
behavior is to wait that long and then retry - not to loop immediately, and not
to re-issue the create without its `idempotency_key`. Tool errors carry the
API's [error envelope](/concepts/errors) verbatim, so an agent can read `code`
and `message` and act on them.
[Polling and Rate Limits](/guides/polling-and-rate-limits) has the full detail.

## 5. Ask for the whole journey

Once connected, the work is expressed as a request rather than as code. For
example:

```text
Using Intuizi: find the POI brands matching "Acme Coffee", build an audience of
devices seen at them in the United States last month, poll it until it is
Completed, and tell me the results count. Do not activate anything yet - show me
the audience first.
```

Then, after you have reviewed it:

```text
Activate audience 88 to my "Acme Production" endpoint connection using the CPM
pricing model, enable the Match File datastream, and poll until the delivery is
Completed.
```

Both halves of that run are ordinary journeys from these guides - the agent is
just holding the pen. Keeping the irreversible step in a second, explicitly
confirmed instruction is the pattern we recommend: `create_activation` and the
delete tools are the ones whose consequences you cannot take back by asking
again.

## Reference

- [MCP Server](/mcp) - what the server is and where it lives
- [MCP > Getting started](/mcp/getting-started) - token and client configuration
- [MCP > Tools reference](/mcp/tools-reference) - every tool and the endpoint it
  wraps
- [Idempotency](/concepts/idempotency) - replay semantics for the five create tools
- [Polling and Rate Limits](/guides/polling-and-rate-limits) - intervals,
  buckets, `Retry-After`
- [The Async Model](/concepts/async-model) and
  [Status Codes](/concepts/status-codes) - why the poll beat exists
- [Deliver to a Partner Endpoint](/guides/deliver-to-a-partner-endpoint) - the
  per-partner detail behind `create_activation`
