---
title: "Release 152"
description: "Run your account from an AI assistant over MCP, move placements and zones without breaking their ad tags, a media library for creative files, CTV video tooling (ISCI / Ad-ID codes, publisher video specs, SSAI stitcher macros, competitive separation in pods), a REST API that covers the console, and a large security and API-quality audit."
type: "reference"
audience: [network-manager, admin]
keywords: [release 152, whats new, mcp, ai assistant, claude, move placement, move zone, placement key, media library, isci, ad-id, universal ad id, ctv, video creative requirements, publisher spec, ssai, stitcher, mediatailor, pod, competitive separation, rest api, ignoredFields, bulk labels, list filters, header bidding, dsp partner, sub1, default vast events, traffic quality, security]
---

Fetch the complete documentation index at: https://epom.com/ad-server/docs/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Release 152

Release 152 is the **API, AI-assistant and CTV release**. Your users can now run their account from
an AI assistant such as Claude, under exactly their own permissions; the REST API reaches what the
console does and says when it did not apply something; and video inventory gets the tooling connected-TV
buyers and publishers expect — ISCI / Ad-ID codes, publisher video specs, server-side ad insertion
(SSAI) support and ad breaks that keep competitors apart. Placements and zones can finally be moved
without breaking the tags already on publishers' pages, and a media library stores a creative file
once for any number of creatives. Alongside: a security and API-quality audit that closes many gaps
where the server did less checking than the console implied.

> **Things to act on.**
>
> **Three new permissions arrive switched off for every role** — *Banner ISCI / Ad-ID Code*,
> *Video Creative Requirements* and *Media Library*. The fields, reports and pages they gate stay
> invisible until an admin grants them; networks that do not sell video see no change.
>
> **DSP partners no longer bid on header-bidding slots by default.** If your network received
> partner bids on header-bidding slots in release 151, ask Epom support or your account manager to switch partner demand on
> and tick **Allow in header bidding** on each partner that should take part. Your directly sold
> campaigns keep bidding either way.
>
> **REST API integrations: read the response body, not only the status.** A refused call that used to
> answer HTTP 200 with `success:false` now answers 400, 403, 404 or 409 with the same body. Scripts
> that write with only a console session cookie need the CSRF token. See
> [API changes to check](#api-changes-to-check).
>
> **Shared placement preview links stop working** — generate a new one from the placement.

## New features

### Run your account from an AI assistant (MCP)

Point an MCP client — Claude, Cursor and others — at your installation's `/mcp` address with your
own API key, and work the account in conversation: create advertisers, campaigns and every creative
type, sites, zones and placements; target, cap and link them; read a campaign's or placement's full
state in one answer; find any entity by name; see your own recent changes and the values they
replaced; run a statistics report; ask why a creative does not serve on a placement; and get a
placement's ad tag and a shareable preview link. Beyond those task tools, the assistant can find and
call any documented REST operation. It acts as you: each tool is offered only if your role can use it,
every call goes through the same permission checks as the console, sign-in and password operations
are never reachable, and everything it changes appears in the action log under your name, marked as
coming from the assistant. A field the server did not apply is reported as *not applied* rather than
done. The endpoint is on by default; Epom can switch it off for a network. See
[Connect an AI assistant (MCP)](https://epom.com/ad-server/docs/api/mcp.md).

### Move placements and zones without breaking their tags

A placement's ad-tag key is now fixed when the placement is created, so a placement can be moved to
another zone, and a zone to another site, while every tag already on a publisher's page keeps
serving. Drop a placement on a zone (or a zone on a site) in the publishers tree and choose **Move**
or **Copy**; the grid clipboard moves them too. **Keep banners linked** now does what it says on a
move: checked, every banner link stays; cleared, every link is dropped. A copy is still a new
placement with a new key. See [Move or copy a zone or placement](https://epom.com/ad-server/docs/guides/inventory/zones.md#move-or-copy-a-zone-or-placement).

### A media library for creative files

Upload a video, an image or an HTML5 ZIP once and pick it in any number of creatives with **Pick from
library** on Local File, Local Video, Advanced Local Video(s) and a template's HTML5 ZIP property. A
CTV master that runs in one creative per publisher is stored once. Creatives reference the file
rather than copying it, library files never change (a corrected spot is a new upload), and deleting a
file from the library never breaks a running creative. Files can be added from disk or from a link,
and identical uploads are recognised and stored once. Users who see every advertiser see every file;
users with shared advertisers see the files uploaded for them. Behind the *Media Library* permission,
and it needs your network's file storage to be enabled. See [Media library](https://epom.com/ad-server/docs/guides/advertising/media-library.md).

### ISCI / Ad-ID codes on video creatives

A video creative can carry its **ISCI / Ad-ID code** and registry, which CTV publishers use to check a
spot and reconcile invoices. Every VAST response for the creative carries it where the VAST version
expects it, the General report can group by it, and the General report and the Impressions, Clicks
and Conversions logs can filter by it. Behind the *Banner ISCI / Ad-ID Code* permission. See
[Video banners](https://epom.com/ad-server/docs/guides/advertising/banner-video.md) and [Analytics dimensions](https://epom.com/ad-server/docs/reference/analytics-dimensions.md).

### Check video creatives against each publisher’s spec

A site can carry the publisher's **Video creative requirements** — resolution, duration, bitrate,
frame rate (including constant frame rate only), container, codecs, audio, file size and loudness — and
**Use a publisher spec** fills them from 15 major streaming publishers' published specs. A video that
misses the spec stays linked but is not served on that site, so the next creative wins, and every
place it is linked says why: a warning on the link cards, a **Not served** mark in the link trees and
grids, and a per-site verdict under the creative's video info. Behind the *Video Creative
Requirements* permission. See [Video creative requirements](https://epom.com/ad-server/docs/guides/inventory/video-creative-requirements.md).

### Server-side ad insertion (SSAI) and ad breaks

- **Name the stitcher.** A video placement's VAST configuration has a **Server-side ad insertion**
  picker — IAB standard macros, Google Ad Manager DAI, AWS Elemental MediaTailor, SpringServe or
  Brightcove. Once set, the VAST and VMAP tags carry that vendor's own macros for the viewer's IP,
  user agent and device ID, and the VAST Tags tab explains each one. Off until you pick a stitcher.
- **Competitive separation in a pod.** A placement that returns an ad break can allow one spot per
  advertiser domain, or per domain and category, so two car brands never run back to back. Whatever
  it is set to, the same spot never plays twice in one break.
- **The viewer, not the stitcher.** Targeting, frequency capping and fraud checks now see the TV or
  app behind a stitcher — its IP, user agent and advertising ID — instead of one data-centre server
  standing in for every viewer.

See [Video placements](https://epom.com/ad-server/docs/guides/inventory/placement-video.md).

### Serve link-based creatives from our own copy

An External File, External Video or External Native creative can tick **Serve from our server**: the
files behind its links are downloaded when the creative is saved, checked like uploads and served from
our storage, so the advertiser's host no longer has to stay up for the whole flight. Every upload in
the new interface can also take a link instead of a file from disk. See
[Image banners](https://epom.com/ad-server/docs/guides/advertising/banner-image.md) and [Video banners](https://epom.com/ad-server/docs/guides/advertising/banner-video.md).

### Affiliate `sub1`…`sub10` parameters pass through

Partners such as Everflow, TUNE and Affise append `sub1=` to a tag or click URL and expect it back on
the conversion. The ad server now accepts `sub1` to `sub10` as custom parameters without a prefix,
`$$SUB1$$`…`$$SUB10$$` substitute them in markup, click and postback URLs, and a placement can carry
default sub-values in its ad-tag settings. See [Macros](https://epom.com/ad-server/docs/reference/macros.md) and
[Ad tags and API](https://epom.com/ad-server/docs/guides/inventory/ad-tags-and-api.md).

### Default VAST tracking events for new video placements and banners

**Admin → Inventory & Campaigns Settings** gets a **Default VAST tracking events** card with one set
for new video placements and one for new video banners. Whatever is ticked is switched on when such an
entity is created, from any interface; existing entities never change. Both sets start empty. See
[Rules and defaults](https://epom.com/ad-server/docs/guides/admin/rules-and-defaults.md).

### DSP partners in header bidding are opt-in

A DSP partner now quotes on header-bidding slots only when partner demand is switched on for the
network and the partner has **Allow in header bidding** ticked. A partner's win is reported to it only
when the creative actually renders, and a partner-priced bid competes in Google Ad Manager on price
rather than taking the line item meant for the network's own sales. See
[DSP partners](https://epom.com/ad-server/docs/guides/admin/dsp-partners.md) and [Header bidding](https://epom.com/ad-server/docs/guides/inventory/header-bidding.md).

### The REST API covers what the console does

Operations that existed only behind console pages are now REST endpoints, and every creative type
can be created from a URL instead of an upload. Every advertiser, campaign, banner, site, zone and
placement list filters by any on/off setting, trims fields and pages; labels can be added, replaced or
removed on up to 500 entities in one call. A save that skips a field — because your role may not set
it, or it is not part of that operation — still succeeds but lists it under `ignoredFields`, with the
reason. See [Entities CRUD](https://epom.com/ad-server/docs/api/entities-crud.md).

## Improvements

- **New placements auto-link by label alone.** A creative's auto-link categories and labels are now
  independent filters: with labels and no categories, every new placement carrying one of the labels
  is linked, whatever its site's categories. Creatives already set up that way start linking after
  the upgrade. The fields are now called **Auto-link site categories** and **Auto-link placement
  labels**. See [Hierarchy and linking](https://epom.com/ad-server/docs/concepts/hierarchy-and-linking.md).
- **API keys on every REST call.** Send your key in the `X-Api-Key` header (or `Authorization: Bearer`) on
  any `/rest-api` call; your role needs *API Key Access*. See [REST API](https://epom.com/ad-server/docs/api.md).
- **Third-party lookup limit removed from the placement form.** It tuned the retired mobile-network
  mediation; existing values stay and need no action.
- **Three IAB sizes in the ad-unit catalogue**: Super Leaderboard / Pushdown (970×90), Portrait
  (300×1050) and Large Mobile Banner (320×100). A size you already created by hand is not duplicated.
- **Conversion-action settings say what they do**: the time frames are now *attribution windows*,
  the per-IP time frame is the *Duplicate conversion window*, and the detailed-log option explains
  what else it needs. Labels only. See [Conversion actions](https://epom.com/ad-server/docs/guides/conversions/conversion-actions.md).
- **Shorter form help.** In the new interface the line under a field is one short hint; anything
  longer sits behind an (i) beside the label, and selects describe their options in the dropdown.
- **Grid columns stop stretching across wide monitors.** Columns settle at their content width and
  cells stay on one line; tables inside cards and dialogs wrap instead of scrolling sideways.
- **The ad-tag card documents pod overrides** (`maxAds`, `maxPodDuration`) and the loader's
  JavaScript API (`init()` and the `ad-loaded` event).
- **The traffic quality score catches more fraud** — declared crawlers, headless browsers, IP and
  browser time-zone countries that disagree (residential proxies) and implausibly fast or
  impression-less clicks — and stops flagging clean placements on networks without Pixalate. See
  [Moderation and quality](https://epom.com/ad-server/docs/guides/admin/moderation-and-quality.md).
- **The role editor drops fifteen permissions that controlled nothing.**
- **Every video creative has a stable VAST creative id and offers its uploaded file as the
  mezzanine**, so SSAI stitchers cache it correctly, and VAST event names follow each VAST version.
- **Frequency caps count TV and in-app viewers by their device ID** instead of a fingerprint shared
  by everyone behind a stitcher.
- **Ad servers keep up with a live ad break**: about half the CPU per ad pod, 10,000 single-ad calls a
  second at a p99 of 15 ms in a local burst test.
- **The non-standard *Ad Opportunity* VAST event and banner field are removed** — no player fires it
  and SSAI stitchers reject it. Past reports keep its rows.

## Bug fixes

- **Rejecting a creative now takes it off the air.** A rejection recorded the verdict but the creative
  kept serving.
- **Video playback events no longer inflate the Conversions column.** Actions bound to VAST tracking
  events (start, quartiles, complete) counted as conversions; their money is billed as before.
- **Header-bidding quotes no longer thin out DSP partners on ordinary serving.**
- **A VAST pod capped by duration alone returned no ad.**
- **Uploading VAST media files and local companion images failed every time** since late 2025.
- **Advanced Local Video files and static VAST companions pointed at a dead link** on networks
  without a file CDN.
- **Placements could not be saved from the new UI on roles without Default Code**, the demo role
  included.
- **Masked inventory showed its real name** on the site and placement cards in the new UI.
- **A paused placement offered a tag to install**; the key and Ad tags & API card are hidden while it
  is off, as in the old interface.
- **The Targeting Cookie report's Week, Month and Year breakdowns** showed one blank row.
- **The report column picker lost its sections in 11 of 15 languages**, and the Header Bidding report
  type read in English in every language.
- **The sites tree failed to load** on networks that still carried placements of a retired type.
- **A 12.5% referral share was stored as 13%**, and **share notification e-mails were never sent.**
- **Security hardening.** The legacy `/rest` API issues login tokens only to an authenticated
  caller, and its tokens expire after five minutes; a statistics account can only be given a role
  its creator may hand out, and new ones get a random password; console writes carry cross-site
  request protection; pages and lists require sign-in and answer only for your own objects; and the
  white-label signing key is no longer publicly readable. Epom has a short list of
  follow-up actions (rotating the white-label key, resetting statistics accounts created from the
  console since release 150).
- **The server enforces the same permissions the console shows.** Endpoints behind hidden or
  locked controls — resetting an entity's delivery counter, for example — now require your own
  entity and the matching write permission, as the console always implied.
- **API writes no longer reset data you did not send.** Pricing CSV uploads zeroed every country
  missing from the file, partial updates reset settings that were not part of the call, and an unknown
  id wiped the stored values while answering success. Omitted now means unchanged, and unknown ids are
  refused with nothing changed.
- **API input the database refused no longer comes back as a server error**; out-of-range values are a
  400 naming the field, and an invalid IP range is no longer saved as `0.0.0.0` (which widened a
  blocking rule to every address).

## API changes to check

If you run scripts or integrations against the REST API, check these before the upgrade reaches your
network:

- A refused `/rest-api` call answers **400 / 403 / 404 / 409** with the same JSON body it used to send
  with HTTP 200 and `success:false`. A refusal names the missing permission; an id you may not see, or
  another customer's deleted entity, is a 404.
- Writes made with only the console session cookie need the **`X-CSRF-TOKEN`** header; API-key and
  signed calls are unaffected.
- Fields your role may not change are **left unchanged and listed in `ignoredFields`** rather than
  silently saved or refusing the whole call; that includes a limit cap you change without its
  permission (a cap re-sent with its stored value needs none) and `linkToPlacements=true` without a
  linking permission.
- Updates keep what they are not sent — a video placement's skip button and pre-roll limit, a
  frequency cap's subject, a limit's local-time flag, preference fields.
- Copy operations take 1–20 copies; an unknown OS version is refused instead of silently widened.
  Kept as before: an unknown analytics column id is dropped from the report (named in the
  `X-Ignored-Report-Columns` response header), link calls link the ids they can and list unknown or
  deleted ones in `skipped`, re-posting a targeting rule that already exists answers `200` with the
  stored rule, a `browserVersion` on a browser without version targeting saves the rule on the whole
  browser (listed in `ignoredFields`), and time ranges take `24:00` and `HH:mm:ss`.
- URL fields over the API follow your network's URL-validation switch, as in the console; `javascript:`,
  `data:` and similar schemes are refused either way, and tracker macros such as `{clickid}`,
  `{{sub1}}`, `[timestamp]` and `%%CACHEBUSTER%%` are accepted.
- A deactivated account's key or signature is refused with `401`, without counting toward the
  address's failed-sign-in block.
- A list `labels` filter naming no existing label returns an empty list; `bannerName` matches any part
  of the name.
- Supply-side (site, zone, placement) targeting needs *Manage Supply Pre-Targeting*; changing a
  banner's approval status needs *Banners Approval* — on banner create and update, a `status` sent
  without it is left as it is and listed in `ignoredFields`, and the rest of the call is saved.
- The creative field and VAST event *Ad Opportunity* are gone; a sent `adOpportunityId` is listed in
  `ignoredFields`.

### For API integrators: what to change

- **Send these as POST** — a GET now answers `405`: the matching-rule calls
  `/rest-api/rules/{entity}/{id}/{enable|disable|add|remove}.do`, `/rest-api/template/delete.do` and
  `/rest-api/network/management/recalculate-balances.do`.
- **Check `ignoredFields` after every write.** A `200` no longer means every field you sent was saved.
- **Read the status of `POST /rest-api/auth/token.do`:** a wrong username or password, an address outside the
  account's IP whitelist or a locked account is a `401` (it used to be `200` with `success:false`), and the message is the same for
  all of them. Repeated failures temporarily block further attempts.
- **Validation errors are keyed by field:** `errors` is a `{field: message}` object, no longer a list of
  messages.
- **Browser code on another site** cannot reuse a console login: use your API key in the `X-Api-Key`
  header. Token login in the JSON or JSONP mode no longer signs the browser in; use the redirect mode.
- **Removed:** `/app/at`, `/sat` and `/contactUs/checkEmail.do` answer `404`. Point in-app postbacks at
  the conversion action's server-to-server postback URL; it matches the conversion by click ID, not by
  device fingerprint, so the postback must pass the click ID back. See
  [Server-to-server postback](https://epom.com/ad-server/docs/guides/conversions/s2s-and-pixels.md#server-to-server-postback).
- **Response shapes that changed:** `banner/dspPartners` returns only `id`, `name`, `type` and
  `parameters`; `piggyback/campaign/get` returns flat `campaignId` / `campaignName`-style fields; a
  campaign pricing CSV upload reports `csvErrors`, `csvWarnings`, `applied` and `rejected`.
- **Writes that are stricter:** a `price` is required on action and country prices; a capping
  `update.do` for a rule that does not exist is a `404` (use `set.do`); limit counters cannot be set;
  changing a campaign's or site's pricing type deletes its existing prices.
- **Deleted entities, your own included, answer `404`.** Treat a `404` on a repeated DELETE as done.

The full list is in the [API reference](https://epom.com/ad-server/docs/api.md).

## Under the hood

Platform upgrades and performance work — live ad breaks are answered with far less server load.
The retired `/sat` action endpoint now answers 404.

## Related

- [Connect an AI assistant (MCP)](https://epom.com/ad-server/docs/api/mcp.md)
- [Media library](https://epom.com/ad-server/docs/guides/advertising/media-library.md)
- [Video creative requirements](https://epom.com/ad-server/docs/guides/inventory/video-creative-requirements.md)
- [Video placements](https://epom.com/ad-server/docs/guides/inventory/placement-video.md)
- [What's new in Epom Ad Server](https://epom.com/ad-server/docs/releases.md)
- [Release 153](https://epom.com/ad-server/docs/releases/release-153.md)
- [Release 151](https://epom.com/ad-server/docs/releases/release-151.md)