# Advertising CLI commands

> Canonical HTML: https://screenrig.ai/docs/cli/ads

Buy ads in a network that invited you or sell ad breaks on your screens: networks, inventory, slots, creatives, campaigns, reviews and reports. Every command here runs as described in the [CLI reference](https://screenrig.ai/docs/cli.md): global flags, JSON output, exit codes, revisions and retries.

## Advertising

Buy advertising in a network that invited you, or sell ad breaks on screens you own. Read `screenrig project capabilities` first: buying needs the `advertiser` feature, selling needs owned screens. Money is reported as decimal mcr strings, where 10,000,000 mcr is US$1. Run `screenrig ads COMMAND --help --json` for every flag. The buying and selling workflow is in [Quickstart](https://screenrig.ai/docs/start.md#signage-buying-or-selling); rates and fees are on [Pricing](https://screenrig.ai/pricing.md).

### `ads networks`

Buyer: list the networks this project was invited into, and inspect one network's permitted inventory and slots.

```console
ads networks list
ads networks show <seller-project-id>
```

```console
screenrig ads networks list
```

### `ads network`

Seller: inspect or create this project's own network and set its default rate.

```console
ads network show
ads network create --name NAME
ads network rate --rate-mcr-per-15s MCR --expect-rev REVISION
```

```console
screenrig ads network rate --rate-mcr-per-15s 1000 --expect-rev 3
```

`--name` is at most 120 characters. `--rate-mcr-per-15s` is a positive whole number of mcr per 15 seconds of completed playback, and `--expect-rev` is the network's `revision` from `ads network show`. A changed effective rate pauses affected campaigns until each buyer accepts a fresh quote.

### `ads inventory`

Seller: opt an owned screen in or out of advertising and describe it to invited buyers.

```console
ads inventory list
ads inventory update <screen-id> [--enabled | --disabled] [--site-name NAME]
    [--city CITY] [--region REGION] [--venue-type TYPE] [--audience-tags TOKENS]
    [--placement TEXT] [--public-description TEXT]
    [--rate-mcr-per-15s MCR | --clear-rate]
    [--impressions-per-hour N | --clear-impressions-per-hour] [--expect-rev REVISION]
```

```console
screenrig ads inventory update scr_LOBBY --enabled --venue-type cafe
```

Omitted flags keep their current values. A new inventory row needs `--enabled` or `--disabled`. `--impressions-per-hour` records your estimate of the impressions the screen delivers in an hour: each completed play then counts that estimate times the seconds played over 3600 as `estimated_impressions` in `ads reports spend`, `ads reports delivery` and `ads direct report`.

`update` needs at least one flag. `--audience-tags` takes up to 20 comma-separated tags, each at most 32 letters, digits or underscores. `--clear-rate` returns the screen to the project's default rate and `--clear-impressions-per-hour` removes the estimate. `--expect-rev` replaces the stored row's revision as the precondition and is refused for a screen with no row yet.

### `ads slots`

Seller: define reusable ad slots. A slot changes nothing on the glass until its adslot page is placed in a playlist.

```console
ads slots list
ads slots create --name NAME --accepted-media image,video
    [--max-image-duration-ms MS] [--max-video-duration-ms MS]
    [--rate-mcr-per-15s MCR | --clear-rate] [--enabled | --disabled] [--vast-tag-url URL]
ads slots update <slot-id> --expect-rev REVISION [--name NAME]
    [--accepted-media image,video] [--max-image-duration-ms MS] [--max-video-duration-ms MS]
    [--rate-mcr-per-15s MCR | --clear-rate] [--enabled | --disabled]
    [--vast-tag-url URL | --clear-vast-tag-url]
```

```console
screenrig ads slots create --name "Lobby break" --accepted-media image,video
screenrig ads slots create --name "Lobby video" --accepted-media video --vast-tag-url https://ads.example.com/vast.xml
screenrig ads slots update ads_LOBBY --clear-vast-tag-url --expect-rev 2
```

A new slot is enabled unless `--disabled` is given. `--accepted-media` is `image`, `video` or both, comma-separated. Omitted duration limits are 30000 ms; an image limit is 5000 to 30000 ms and a video limit 5000 to 120000 ms. `--rate-mcr-per-15s` is a positive whole number that overrides the screen or project rate for this slot, and `--clear-rate` removes the override. `update` keeps every field you omit, and a changed effective rate pauses affected campaigns until each buyer accepts a fresh quote. `--vast-tag-url` is an HTTPS URL of at most 2048 characters.

`--vast-tag-url` sets the seller's own VAST 2-4 ad tag, tried when no invited campaign fills the slot on your own screens; the slot must accept video. The URL is HTTPS on port 443 or 8443 to a public host. The backend fetches it, follows up to five Wrappers, ingests the chosen progressive MP4 or WebM into the project's media, and fires Impression, creativeView and start on an accepted start, complete on an accepted completion, and Error on failure; there are no quartile trackers. The macros `[CACHEBUSTING]`, `[TIMESTAMP]`, `[SCREENRIG_SCREEN_ID]`, `[SCREENRIG_SLOT_ID]` and `[SCREENRIG_PAGE_ID]` are expanded, and buyers never see the tag. On `update`, `--vast-tag-url` replaces the tag and `--clear-vast-tag-url` removes it; the two do not combine, and omitting both keeps the stored tag. `ads slots list` shows `vast_tag_url` to the owning seller. A slot that nothing can fill on a screen (no VAST tag and, on a screen opted in to advertising, no direct campaign that has not ended and no active, pending or paused invited campaign naming it) is left out of that screen's manifest, and `screen show` lists it in `ad_quiet_slots`, so the Player stops asking. A campaign, tag or opt-in that could fill it brings it back.

### `Advertising invitations`

Use the shared `invitations` commands above:

```console
screenrig invitations create --kind ad-buyer --email owner@bakery.example --screen-id scr_LOBBY --policy review_required
screenrig invitations list --kind ad-buyer
screenrig invitations revoke ID
```

An ad-buyer invitation goes by email, never by link, and needs at least one `--screen-id` or `--slot-id` (comma-separated). `--policy` is `trusted` (the default) or `review_required`.

The invited person accepts in the dashboard. A signed-in person selects their
buying project and confirms with a fresh passkey proof. A person
without a login creates one and an advertiser-only project during acceptance.

### `ads memberships`

Seller: change or revoke an admitted buyer's review policy and inventory scope.

```console
ads memberships list
ads memberships update <membership-id> --expect-rev REVISION
    [--policy trusted|review_required] [--screen-id IDS] [--slot-id IDS]
ads memberships revoke <membership-id>
```

```console
screenrig ads memberships list
```

`update` keeps the stored policy and scope for omitted flags. `trusted` plays the buyer's creatives without review; `review_required` holds each creative version for your decision. `--screen-id` and `--slot-id` take comma-separated ids and replace the whole list, and an empty value allows none.

Revocation stops new ad plays and keeps financial history.

### `ads creatives`

Buyer: bind ready owned media to an immutable creative with approved copy.

```console
ads creatives list
ads creatives create --media-id ID --copy TEXT
ads creatives show <creative-id>
```

```console
screenrig ads creatives create --media-id med_123 --copy "Fresh bread daily"
```

Binding a creative charges nothing and does not upload the media again. An approved creative never changes in place: edit the source media and bind a new creative. `--copy` is at most 500 characters. `show` lists each seller network's review of the creative (`pending`, `approved`, `rejected` or `changes_requested`) with the seller's reason.

### `ads campaigns`

Buyer: draft a campaign, price it, and activate it by accepting the quote.

```console
ads campaigns list
ads campaigns show <campaign-id>
ads campaigns create <file>
ads campaigns update <campaign-id> <file> --expect-rev REVISION
ads campaigns preview <campaign-id> [--expect-rev REVISION]
ads campaigns activate <campaign-id> --quote-id ID --expect-rev REVISION
ads campaigns pause <campaign-id> --expect-rev REVISION
ads campaigns resume <campaign-id> --expect-rev REVISION
ads campaigns accept-rates <campaign-id> --quote-id ID --expect-rev REVISION
```

```console
screenrig ads campaigns preview cmp_123
```

A draft reserves nothing. `preview` returns a time-limited quote and spends nothing; `activate` requires that exact quote. After a seller rate change, only `accept-rates` with a fresh quote resumes the campaign.

`<file>` is a JSON file, or `-` for standard input, and `update` replaces a draft with the whole document. The draft names `name`, `daily_cap_mcr`, `lifetime_cap_mcr` (at least the daily cap), `flight_start` and `flight_end` (RFC 3339) and `networks`, one entry per seller network the project joined, each with `seller_project_id`, `screen_ids`, `slot_ids`, `creative_ids` and optionally `venue_types`, `cities`, `tags`, `dayparts` and `network_cap_mcr`. Money fields are decimal mcr strings, never numbers. `image_duration_ms` (5000 to 30000, ten seconds when omitted) sets how long an image shows, and `max_play_price_mcr` caps the price of one play; omit it for no ceiling.

A campaign draft takes an optional `category` from the advertiser category list. Two ads of one category never play in the same ad break on a screen.

`preview` reads the campaign's current revision unless `--expect-rev` names one. `pause` stops new reservations; plays already started finish and settle at their reserved price. `resume` restarts a manually paused campaign and cannot clear a price-change pause.

### `ads direct`

Seller: book your own deals for advertisers outside screenRIG on your own screens.

```console
ads direct list
ads direct show <campaign-id>
ads direct create <file>
ads direct update <campaign-id> <file> --expect-rev REVISION
ads direct pause <campaign-id> --expect-rev REVISION
ads direct resume <campaign-id> --expect-rev REVISION
ads direct end <campaign-id> --expect-rev REVISION
ads direct availability <file>
ads direct report <campaign-id> [--from TIME] [--to TIME]
    [--format json|csv|xlsx|pdf] [--output FILE|-]
```

```console
screenrig ads direct create campaign.json
```

A draft names `name`, `advertiser`, an optional `category`, `flight_start` and `flight_end`, `media_ids` (1 to 20 of your own ready images or videos), an optional `goal_plays`, an optional `price` (`model` `cpm` per thousand plays or `flat`, with an `amount` and an ISO 4217 `currency`), an optional `image_duration_ms` (5000 to 30000, ten seconds when omitted) and targeting: `screen_ids`, `slot_ids`, `venue_types`, `cities`, `tags` and `dayparts` (such as `{"days": ["mon"], "start": "11:00", "end": "14:00"}`), where an empty list means every opted-in screen or slot. A direct campaign fills an ad break before invited buyers. A goal is paced evenly across the flight and plays first while behind pace; a campaign without a goal takes every eligible slot during its flight. No money moves through screenRIG: you bill the advertiser, and the price values the report.

`<file>` is a JSON file, or `-` for standard input. `category`, here and in a campaign draft, is one of `alcohol`, `apparel`, `automotive`, `beauty`, `cannabis`, `consumer_electronics`, `education`, `entertainment`, `financial_services`, `food_and_beverage`, `gambling`, `government`, `grocery`, `health_and_pharma`, `home_and_garden`, `insurance`, `jobs`, `legal`, `media`, `political`, `quick_service_restaurants`, `real_estate`, `restaurants`, `retail`, `sports_and_fitness`, `technology`, `telecom`, `tobacco_and_vaping`, `travel` or `utilities`. `update` replaces every writable field, so send the whole document. `pause` stops a campaign taking ad slots and `resume` restores it; a goal campaign that fell behind pace while paused plays first until it catches up. `end` is final: an ended campaign plays no more, cannot be resumed and keeps its report.

`availability` reads a query with the same targeting and flight and estimates the plays you can still book: the targeted screens' recent ad slot occurrences, less the plays your other direct goals still need. It answers `estimated_plays`, `booked_plays` and `available_plays`, and `exclude_campaign_id` leaves the campaign you are editing out of `booked_plays`. A goal above the estimate returns `goal_overbooked` unless the draft sets `"overbook": true`.

`report` lists plays against the goal, pace, value, plays that did not play, and rows by UTC day, screen, slot and media. `--from` and `--to` take an RFC 3339 instant, `now` or an age such as `7d`, `12h` or `30m`, and default to the flight. `--format csv`, `xlsx` or `pdf` writes the rows to `--output` (default `./direct-report-CAMPAIGN_ID.FORMAT`) and answers with its path, bytes and SHA-256; with `--format csv`, `--output -` writes the CSV to standard output instead. The CSV columns are `day`, `screen_id`, `slot_id`, `media_id`, `plays`, `played_ms` and `estimated_impressions`. A JSON or CSV report lists at most 5000 rows and carries the warning `direct_report_truncated` when more exist: narrow `--from` and `--to` for the rest.

Creating, replacing and resuming a direct campaign, `availability` and `report` need a plan that includes direct campaigns; other plans are refused with `feature_not_in_plan`. `screenrig project capabilities` lists the plan's features.

### `ads reviews`

Seller: approve, reject or request changes to exact submitted creative versions from buyers on `review_required`.

```console
ads reviews list
ads reviews show <review-id>
ads reviews approve <review-id>
ads reviews reject <review-id> --reason TEXT
ads reviews request-changes <review-id> --note TEXT
```

```console
screenrig ads reviews request-changes arv_123 --note "Use the new logo"
```

`request-changes` sends the buyer your note. To submit the revision, bind the
revised media as a new creative, add it to a new campaign, run `preview` and
`activate` against the fresh quote. The replacement has its own budget and
review history. Pause the original campaign before activating its replacement
to avoid overlapping delivery. People decide ad creatives in the dashboard's
Reviews page, beside playlist and screen changes.

`list` shows the creative versions awaiting your decision and `show` one submission with its exact creative. `--reason` and `--note` are required and at most 500 characters; the buyer reads them on the creative (`ads creatives show`). Deciding needs Manage access.

### `ads reports`

Read spend as a buyer or delivery as a seller.

```console
ads reports spend --campaign-id ID [--format json|csv|xlsx|pdf] [--output FILE]
ads reports delivery --from TIMESTAMP --to TIMESTAMP
    [--format json|csv|xlsx|pdf] [--output FILE]
ads reports fill [--from TIME] [--to TIME] [--format json|csv|xlsx|pdf] [--output FILE]
```

```console
screenrig ads reports delivery --from 2026-09-01T00:00:00Z --to 2026-10-01T00:00:00Z
```

Delivery reports gross, serving fee and net for the period. A buyer report never shows a seller's other income. `fill` shows, for up to 35 days, how many ad slot occurrences your screens asked for, how many direct campaigns, invited buyers and your VAST tag filled, and why the rest stayed empty: `no_demand`, `ineligible`, `separated` or `capped`.

`--format csv`, `xlsx` or `pdf` writes the report as a file to `--output` (default `./ad-spend.FORMAT`, `./ad-delivery.FORMAT` or `./ad-fill.FORMAT`) and answers with its path, bytes and SHA-256; `json` is the default and prints the envelope. `delivery` needs `--from` and `--to` as RFC 3339 instants and lists one row per completed occurrence, at most 5000, with `truncated` set when more exist; the totals cover every settlement. `fill` takes an RFC 3339 instant, `now` or an age such as `7d`, `12h` or `30m`: `--from` defaults to 7 days before `--to`, `--to` to now, at most 35 days apart, widened to whole UTC hours.

## Other command groups

- [Projects](https://screenrig.ai/docs/cli/projects.md)
- [Service clients](https://screenrig.ai/docs/cli/service-clients.md)
- [Help and support](https://screenrig.ai/docs/cli/help.md)
- [Media](https://screenrig.ai/docs/cli/media.md)
- [Media sync](https://screenrig.ai/docs/cli/media-sync.md)
- [Playlists](https://screenrig.ai/docs/cli/playlists.md)
- [Cards](https://screenrig.ai/docs/cli/cards.md)
- [Applications](https://screenrig.ai/docs/cli/applications.md)
- [Screens](https://screenrig.ai/docs/cli/screens.md)
- [Schedules](https://screenrig.ai/docs/cli/schedules.md)
- [Campaigns](https://screenrig.ai/docs/cli/campaigns.md)
- [Device health](https://screenrig.ai/docs/cli/device.md)
- [Reviews and notes](https://screenrig.ai/docs/cli/reviews.md)
- [Notifications](https://screenrig.ai/docs/cli/notifications.md)
- [Reports](https://screenrig.ai/docs/cli/reports.md)
- [Data sources](https://screenrig.ai/docs/cli/data-sources.md)
- [BI dashboards](https://screenrig.ai/docs/cli/bi.md)
- [Triggers](https://screenrig.ai/docs/cli/triggers.md)
- [Fleet links](https://screenrig.ai/docs/cli/fleet-links.md)
