# October 2026


## 2026-10-11

- **Client registration accepts only plain redirect URIs** {{< products "MCP" >}}

  [Dynamic client registration](/api/v2/authentication#registration-constraints)
  now rejects a redirect URI that contains a backslash, a comma, `@`, `%`,
  `#`, a space or a control character, whose host is not a plain host name
  (for example a trailing dot or an empty port), or whose port is outside 1 to
  65535. The answer is `400` with `invalid_redirect_uri`. The redirect URIs
  that MCP clients register today are unaffected, and clients that are already
  registered keep working.

## 2026-10-09

- **Index Exchange: the IX CPM, the visibility and what each pricing model delivers** {{< products "API" "MCP" "Console" >}}

  An Index Exchange activation now carries the segment's marketplace CPM
  (`IX CPM USD`, required, 0.01 to 99.99) and its visibility (`IX Access`,
  `public` or `private`, default `public`).
  [Create Activation](/api/v2/activations#index-exchange) and
  [Create Schedule](/api/v2/schedules#post-apiv2analysesschedulescreate) refuse
  a missing or invalid CPM, an invalid access value or segment id, and a CTV
  audience with a `422` that names the rule. An Index Exchange connection needs
  no credentials (`requires_credentials: false` in
  [Get Endpoint Connections](/api/v2/common#get-apiv2analysesreferencecommonendpoint-connections))
  and can be used only by the organizations Index Exchange is enabled for.
  [Get Pricing Models](/api/v2/common#get-apiv2analysesreferencecommonpricing-models)
  returns each model's `identifiers` and, for Index Exchange, a
  `delivery_label`. Get Activation and the `activation.completed` webhook
  return `delivery.index_exchange`: the segment, the delivered file and the
  publication state (`null` for every other partner). A scheduled Index
  Exchange activation refreshes one segment once a cycle has registered it.

## 2026-10-04

- **Activations can limit by lookalike score, spend and transactions** {{< products "API" "MCP" >}}

  [Create Activation](/api/v2/activations#activation-limits) takes the limits
  the Audience Manager offers: a score range for a Lookalike Model audience
  (`score_limit` with `min_score` and `max_score`), and for an audience of one
  Transactions dataset, spend and transaction ranges per person
  (`affinity_spend_limit` and `affinity_txn_limit` with their bounds). As with
  the frequency filter, each limit needs its flag, and a limit the audience
  cannot take is rejected with `422`. The activation's `filters` echo them.
  [Create Schedule](/api/v2/schedules#post-apiv2analysesschedulescreate) takes
  the spend and transaction limits in its `activation` block, and the
  `create_activation` MCP tool lists the new fields.

- **Create Activation sends the audience's full definition, as the console does** {{< products "API" >}}

  [Create Activation](/api/v2/activations#post-apiv2analysesactivationscreate)
  now builds what it hands to delivery from the audience exactly as the
  Audience Manager does. Activating a lookalike audience used to return a
  `500`, and a Competitors audience's activation failed during delivery; both
  now work. A single cohort's metadata columns are delivered with it, and every
  other dataset type carries its full definition instead of only its dates.

- **Attribute groups (All or Any of) for Profile Attributes** {{< products "API" "MCP" "Console" >}}

  A Profile Attributes dataset can now group its attributes. Each group is All
  (every attribute in it must match) or Any of (at least one must), and a
  device must satisfy every group, so "all of these, and at least one of
  those" fits in one dataset. In the Audience Manager use **Add group**; on
  [Create Audience](/api/v2/audiences#post-apiv2analysesaudiencescreate) and
  [Estimate Audience Size](/api/v2/audiences#post-apiv2analysesaudiencesestimate)
  send `profile_attribute_groups` instead of `profile_attributes`. Up to 5
  groups. `profile_attributes` keeps working as before, with one change: a
  `group` or `match` key on one of its rows was ignored until now and is
  rejected with a `422` that names the key.
