# CTV App Identity

Source: https://docs.ezoic.com/docs/ctv/app-identity/


If you monetize an app or streaming channel rather than a website, buyers verify who you are before they bid. They check a chain of public records, and a break anywhere in that chain means no bids. Nothing returns an error when this happens. You just get no fill.

## The validation chain

```
bundle  →  store listing  →  developer website  →  app-ads.txt
```

1. Your tag request carries your **bundle**, the app identifier.
2. The buyer looks up the store listing for that bundle and reads the developer website declared there.
3. The buyer fetches `https://<developer website>/app-ads.txt` and checks that the seller IDs in the auction are authorized.
4. Only then does the buyer bid.

## Step 1: Register the app with Ezoic

In your Ezoic dashboard, go to **Ezoic Ads → Mobile & CTV Apps → Add Mobile App**.

| Field | What to enter |
|---|---|
| Platform | Roku, Android, iOS or tvOS, depending on your app. |
| Bundle or channel ID | Roku: your numeric Channel Store ID, for example `123456`. Android and Fire TV: package name, for example `com.example.tvapp`. iOS and tvOS: numeric App Store ID. |
| App name | The name as listed in the store. |
| Store URL | Roku: leave it blank. It is derived from the channel ID. Other platforms: your store listing URL. |

Ezoic reviews the app. Your dashboard shows review progress in stages, and an app is not monetized until its review completes.

The same registration can be done through the publisher MCP `mobile_apps` tool with `platform: "Roku"`.

Registration matters for app-ads.txt approval. An unregistered app cannot complete the validation chain.

**Roku channels** must be published in the Roku Channel Store. An unpublished beta channel has no public listing, so buyers cannot validate it, and it is not supported for monetization.

## Step 2: Publish app-ads.txt

`app-ads.txt` is the app version of ads.txt. It lives at the root of the developer website named in your store listing:

```
https://yourdomain.com/app-ads.txt
```

- Ezoic provides the exact lines to publish. They cover Ezoic's seller IDs and its demand partners. Confirm with your Ezoic contact how your file is maintained.
- The domain serving the file must match the developer website in your store listing exactly. Buyers resolve it from the store, not from your tag.
- Buyers recrawl on their own schedule. Publish the file well before launch.

## Step 3: Send app identity on every request

```
bundle=<app ID>&app_domain=<your Ezoic domain>&app_name=<name>&storeurl=<listing URL>
```

- `bundle` must match the store exactly: the numeric Channel Store ID on Roku, the package name on Android, the numeric ID on Apple platforms.
- On Roku, read the ID at runtime (`roAppInfo.GetID()`) rather than hardcoding it. Sideloaded builds report `dev`, and store installs report the real channel ID.
- `app_domain` ties the request to your Ezoic property for reporting and configuration.
- `storeurl` should be the canonical listing URL.
- Add `app_cat` for the app's IAB categories. Add `inventorypartnerdomain` if you operate under a reseller arrangement.

Do not send `url` or `d` for an app. Those parameters identify a website, and a request that carries them is treated as a site request.

## Reseller arrangements

If you sell inventory on behalf of someone else, or someone sells it for you:

1. `inventorypartnerdomain` must name the inventory partner's domain, and that partner's app-ads.txt must authorize the sellers.
2. The supply chain (`schain`) must include every hop. Ezoic adds its own node. An upstream intermediary must serialize its node correctly, or omit `schain`, because a malformed chain is dropped.

## Checklist

- [ ] App registered in the Ezoic dashboard and approved
- [ ] Store listing is live, and its developer website is a domain you control
- [ ] `https://<that domain>/app-ads.txt` returns the lines Ezoic provided
- [ ] Every request sends `bundle`, `app_domain`, `app_name` and `storeurl`
- [ ] The bundle in the tag exactly matches the store identifier
- [ ] For resellers: `inventorypartnerdomain` is set and the partner's app-ads.txt is updated

