# List stored Ads

> For the complete documentation index, see [llms.txt](https://www.shortsintel.com/llms.txt). Every docs page is also available as markdown: add .md to its URL. To connect, read [agents.md](https://www.shortsintel.com/agents.md).

GET `/v1/trackers/{id}/ads`

Every Ad stored for this Advertiser Tracker, paused too, with no Run: stopped and removed Ads included, newest start first, unknown starts last. Filters skip Ads with no value. Other kinds answer `unsupported_kind`.

Each Ad carries `analysis` `{ summary, hook_type, angle, offer_type, format }`, or null. The analysis filters skip Ads with none.

## Price

Free.

## Parameters

| Name | In | Type | Required | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `id` | path | `string` | Required | — | Tracker id. |
| `status` | query | `string` one of `active`, `inactive`, `all` | Optional | `all` | `inactive` includes removed Ads. Only `all` keeps Ads whose state is unknown. |
| `country` | query | `string` | Optional | — | ISO-2. Matches the newest observation that named countries. Meta names none for commercial Ads, so those never match. |
| `started_after` | query | `string` | Optional | — | ISO date, inclusive. |
| `started_before` | query | `string` | Optional | — | ISO date, exclusive. |
| `stopped_after` | query | `string` | Optional | — | ISO date, inclusive. |
| `stopped_before` | query | `string` | Optional | — | ISO date, exclusive. |
| `media_type` | query | `string` one of `video`, `image`, `carousel` | Optional | — | The Ad's format. |
| `hook_type` | query | `string` one of `QUESTION`, `BOLD_CLAIM`, `PROBLEM`, `STORY`, `DEMONSTRATION`, `LISTICLE`, `CONTROVERSY`, `SOCIAL_PROOF`, `CURIOSITY_GAP`, `DIRECT_ADDRESS`, `NONE` | Optional | — | Image Ads have no hook, so they never match. |
| `angle` | query | `string` one of `PROBLEM_SOLUTION`, `BENEFIT`, `SOCIAL_PROOF`, `SCARCITY_URGENCY`, `PRICE_VALUE`, `AUTHORITY`, `CURIOSITY`, `TRANSFORMATION`, `FEAR_OF_MISSING_OUT`, `COMPARISON`, `STORY`, `ANNOUNCEMENT`, `OTHER` | Optional | — | Video Ads analysed before this field never match. |
| `offer_type` | query | `string` one of `DISCOUNT`, `FREE_TRIAL`, `FREE_SHIPPING`, `FREE_GIFT`, `BUNDLE`, `LIMITED_TIME`, `GUARANTEE`, `LEAD_MAGNET`, `NONE` | Optional | — | `NONE` is an Ad with no offer found. Video Ads analysed before this field never match. |
| `format` | query | `string` one of `TALKING_HEAD`, `VOICEOVER_BROLL`, `SCREEN_RECORDING`, `TUTORIAL`, `UNBOXING`, `BEFORE_AFTER`, `SKIT`, `VLOG`, `SLIDESHOW`, `GREEN_SCREEN`, `SPLIT_SCREEN`, `COMPILATION`, `PRODUCT_DEMO`, `OTHER`, `PRODUCT_SHOT`, `LIFESTYLE`, `UGC_STYLE`, `TESTIMONIAL`, `INFOGRAPHIC`, `TEXT_ONLY`, `MEME`, `SCREENSHOT`, `COLLAGE`, `ILLUSTRATION` | Optional | — | The production format, on image and video Ads. |
| `min_days_running` | query | `integer` min 0; max 99999 | Optional | — | Least `days_running`. A removed Ad's days end at its removal when no stop date was read. A stopped Ad with no stop or removal date has none, so it never matches. |
| `include` | query | `string` one of `intelligence` | Optional | — | `intelligence` adds each Ad's full analysis. |
| `limit` | query | `integer` min 1; max 100 | Optional | `25` | Items per page. |
| `cursor` | query | `string` | Optional | — | Opaque `next_cursor` from the previous page. |

## Responses

### 200 OK

`{ items, next_cursor }`.

object

A page of a list. `items` holds the page; pass `next_cursor` back as `cursor` for the next one.

- `next_cursor` string required nullable Pass back as `cursor`. Null on the last page.
- `items` array of object required
  - `library` string required one of `meta`, `tiktok`, `google`
  - `id` string required
  - `url` string required nullable
  - `advertiser` object required
    - `id` string required nullable
    - `name` string required nullable
  - `is_active` boolean required nullable False once stopped or removed. Null when no observation says.
  - `first_shown` string required nullable
  - `last_shown` string required nullable
  - `placements` array of string required
  - `creative` object required
    - `title` string required nullable
    - `body` string required nullable
    - `cta` string required nullable
    - `link_url` string required nullable
    - `format` string required nullable
    - `image_urls` array of string required
    - `video_urls` array of string required
    - `thumbnail_urls` array of string required
  - `reach` object required Ranges as the library reports them, never coerced. Meta discloses spend and impressions for political and issue Ads, and reach (`audience`) for some EU Ads; otherwise null. TikTok reports `audience` (a bucket such as `10K-100K`); `spend` is null, and `impressions` is null except on a single-Ad lookup.
    - `impressions` string required nullable
    - `spend` string required nullable
    - `currency` string required nullable
    - `audience` string required nullable
  - `kind` string nullable one of `commercial`, `political`, `issue` Meta and Google.
  - `media_type` string required nullable one of `video`, `image`, `carousel` Meta and TikTok. Null when not stored.
  - `countries` array of string required nullable Null on Meta commercial Ads and unread TikTok details.
  - `variant_count` number nullable Meta only. How many Ads share this Ad's media; null for a single Ad.
  - `days_running` integer required nullable Start to stop, else to removal, else to now. Null with no start, or when an Ad known stopped has no stop or removal date.
  - `variations` array of object Google only. Each version of the Ad's copy and media. A video Ad's YouTube id sits here when Google shows one, which not every video Ad has; `creative.video_urls` stays empty.
    - `headline` string required nullable
    - `description` string required nullable
    - `all_text` string required nullable
    - `destination_url` string required nullable
    - `visible_url` string required nullable
    - `image_urls` array of string required
    - `video_id` string required nullable
    - `youtube_url` string required nullable
  - `details_failed` boolean Google search only. True when this Ad's details could not be read: it holds only the list row and is not charged or stored.
  - `archived` boolean True when every media URL is our permanent archived copy; false while any is still the library's expiring URL (retried on the next sighting).
  - `winner_score` object nullable Meta only. How strongly the Ad looks like a winner. 0 to 100, computed from the stored history of the Ad, never fetched. score = round(100 x (0.7 x rank(days_running) + 0.3 x rank(variants_added))), where rank is the share of the Advertiser's other Ads below this one (ties count half) and variants_added is the variant count at the latest Snapshot minus at the first. With one Snapshot the score is round(100 x rank(days_running)), confidence low, reason single_snapshot. With no other dated Ad of the Advertiser, rank falls back to min(days, 90)/90 and min(variants, 5)/5; under 5 dated Ads of the Advertiser the score is low confidence, reason few_advertiser_ads. No start date: score null, reason no_start_date.
    - `score` number required nullable
    - `confidence` string required one of `high`, `low`
    - `inputs` object required
      - `days_running` number required nullable
      - `variants_added` number required
      - `snapshots` number required
      - `advertiser_ads` number required Dated Ads of this Advertiser stored so far, this one included.
    - `reason` string required nullable one of `single_snapshot`, `few_advertiser_ads`, `no_start_date`
  - `intelligence` any of 2 shapes nullable Only with `include=intelligence`. Null with none stored.
    - Option 1 object Video Ads: the full video analysis, read from the archived video with the ad copy as context, plus `offer`, `copy`, and detected shots, the product's first appearance and the opening frame under `structure`.
      - `version` integer required
      - `model` string required
      - `computed_at` string required
      - `source` string required
      - `content` object required
        - `summary` string required
        - `niche` string required
        - `languages` array of string required
        - `content_styles` array of string required
        - `keywords` array of object required
          - `keyword` string required
          - `category` string required
          - `sentiment` number required
        - `transcript` string required nullable What is said, one line per line: the Platform's captions or speech-to-text, never the scene breakdown. Empty with no speech; null when it could not be read.
        - `transcript_source` string required nullable one of `caption`, `whisper` `caption`: the Platform's caption track. `whisper`: speech-to-text on the audio. Null when `transcript` is null, and on analysis stored before 2026-11-09.
        - `transcript_segments` array of object required nullable Timed transcript lines (ms from the start), to see when the hook lands. From the Platform's timed captions when it has them, otherwise measured from the video's audio with speech-to-text. Spoken timing here is measured; times in `structure.scenes` are approximate. Empty when the video has no speech, music-only videos included. Null when the timing could not be measured, on a YouTube Video with no captions, and on older analyses.
          - `start_ms` integer required
          - `end_ms` integer required
          - `text` string required
      - `hook` object required
        - `opening_line` string required nullable
        - `type` string required
        - `visual_hook` string required nullable
        - `rationale` string required nullable
      - `persuasion` object required
        - `call_to_action` object required
          - `type` string required
          - `text` string required nullable
        - `sponsored` boolean required Whether the video is plausibly a paid promotion. Always true when the Platform labels it an ad or a paid partnership.
        - `sponsorship_signals` array of string required
        - `brands_and_products` array of object required
          - `name` string required
          - `kind` string required
          - `prominence` string required
        - `trend_references` array of object required
          - `name` string required
          - `kind` string required
      - `tone` object required
        - `sentiment_label` string required
        - `sentiment_score` number required
        - `primary_emotion` string required
        - `emotion_intensity` number required nullable
        - `emotion_rationale` string required nullable
        - `speaking_style` string required
        - `speaking_style_notes` string required nullable
      - `visual` object required
        - `format` string required
        - `setting` string required
        - `face_visibility` string required
        - `on_screen_text` array of string required
        - `has_on_screen_captions` boolean required
        - `camera_notes` string required nullable
        - `lighting_notes` string required nullable
        - `elements` any
      - `safety` object required
        - `brand_safety_tier` string required
        - `reasons` array of string required
        - `notes` string required nullable
      - `structure` object required When things happen inside the creative: the timed scenes every analysis carries, plus the shots detected, when the product is first seen and the opening frame on a video Ad.
        - `scenes` array of object required The timed scenes, read from the stored scene breakdown. Times are approximate, to about a second. Empty when the breakdown has no timed scenes, as on a photo carousel.
          - `start_ms` integer required Approximate scene start, ms from the start.
          - `end_ms` integer required Approximate scene end, ms from the start.
          - `visual` string required nullable
          - `text_overlay` string required nullable Text shown in this scene, listed at its first appearance: text repeated from an earlier scene is left out.
          - `speech` string required nullable
          - `audio` string required nullable Notable sound effects or music.
        - `shots` array of object required nullable The detected shots in order, each from one cut to the next. A cut is a frame whose ffmpeg scene score is over 0.2. On 29 labelled Ads this found 86% of hard cuts within 500 ms (median error 67 ms) and 61% of jump cuts overall, but none on UGC Ads. Null when detection failed, and on analysis stored before shots.
          - `start_ms` integer required Shot start: the cut before it, or 0.
          - `end_ms` integer required Shot end: the next cut, or the video's end.
        - `cuts_per_minute` number required nullable Detected cuts per minute of video, to two decimals. Null whenever `shots` is.
        - `avg_shot_ms` integer required nullable The video's length over its number of shots, in ms. Null whenever `shots` is.
        - `product_first_seen_ms` integer required nullable When the promoted product first appears (the item, its packaging or logo, or an app's screen), as the start of that scene in ms, so approximate to one scene. On 26 labelled Ads that show one, it was within 3 s of the labelled time on 23 (88%). Null when no product is shown, and on analysis stored before it.
        - `first_frame` string required nullable What the video's opening frame shows, as text: a description, not a time. Read from the first scene's `**Opening Frame:**` line in the scene breakdown. Checked against the video on 10 Ads, it was accurate on all 10. Null when the breakdown has no opening frame, and on analysis stored before it.
      - `pipeline` string required always `video`
      - `offer` object required nullable The offer, in the same types as an image Ad's `offer`. Null when the extraction failed and on analysis stored before this field.
        - `type` string required
        - `text` string required nullable
      - `copy` object required nullable The persuasion angle, in the same values as an image Ad's `copy.angle`. Null when the extraction failed and on analysis stored before this field.
        - `angle` string required
        - `rationale` string required nullable
    - Option 2 object Image and carousel Ads: the analysis an image can carry, read from the archived images with the ad copy as context.
      - `pipeline` string required always `image`
      - `version` integer required
      - `model` string required
      - `computed_at` string required
      - `images_analyzed` integer required
      - `summary` string required
      - `copy` object required
        - `angle` string required
        - `rationale` string required nullable
        - `headline` string required nullable
      - `offer` object required
        - `type` string required
        - `text` string required nullable
      - `call_to_action` object required
        - `type` string required
        - `text` string required nullable
      - `visual` object required
        - `format` string required
        - `on_image_text` array of string required
      - `topics` array of string required
      - `tone` object required
        - `sentiment_label` string required
        - `sentiment_score` number required
  - `intelligence_error` object Why `analyze` left `intelligence` null: no analysis charge. Its fields are on [Errors](https://www.shortsintel.com/docs/reference/errors).
  - `advertiser_account` object nullable TikTok lookup only. The TikTok account the Ad ran from.
    - `username` string required
    - `display_name` string required nullable
    - `followers` string required nullable As TikTok shows it (`9.3M`), not a number.
    - `verified` boolean required nullable
    - `url` string required nullable
  - `targeting` object nullable TikTok lookup only. Where and to whom the ad library says the Ad was delivered, impressions as ranges per country by age and gender. Null when the Ad came from Creative Center.
    - `countries` array of string required
    - `impressions` string required nullable
    - `audience_size` string required nullable
    - `ages` array of string required Age ranges targeted (`18-24`).
    - `genders` array of string required Genders targeted (`female`, `male`, `unknown`).
    - `by_country` array of object required
      - `country` string required
      - `impressions` string required nullable
      - `breakdown` array of object required
        - `age` string required
        - `gender` string required
        - `impressions` string required nullable
  - `performance` object nullable TikTok lookup only. Creative Center's engagement figures, when the Ad is a Creative Center Top Ad; null for an Ad only the ad library holds.
    - `ctr` number required nullable Click-through rate as a fraction (0.46 is 46%).
    - `likes` number required nullable
    - `comments` number required nullable
    - `shares` number required nullable
  - `objective` string nullable TikTok lookup only. The Ad's objective (`Traffic`).
  - `stopped_at` string required nullable TikTok infers it from the last day shown.
  - `removed_from_library` boolean required
  - `removed_at` string required nullable When we first found the Ad gone from the library.
  - `analysis` object required nullable Null when the Ad has no stored analysis.
    - `summary` string required
    - `hook_type` string required nullable Null on image Ads.
    - `angle` string required nullable Null on older video Ads.
    - `offer_type` string required nullable `NONE`: no offer found. Null on older video Ads.
    - `format` string required

### 400 Bad Request

`invalid_request` for a `cursor` that is not a `next_cursor` this API issued. Nothing is charged.

Code: `invalid_request`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

### 401 Unauthorized

Codes: `missing_authorization`, `invalid_key`, `key_revoked`, `key_expired`, `invalid_token`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

### 404 Not Found

`not_found` — also a deleted Tracker, or another Customer's.

Code: `not_found`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

### 422 Unprocessable Content

`unsupported_kind` — not an Advertiser Tracker. Nothing is run or charged.

Code: `unsupported_kind`. The problem body and every code are on [Errors](https://www.shortsintel.com/docs/reference/errors).

## Related guides

- [Pagination](https://www.shortsintel.com/docs/concepts/pagination): Following `next_cursor` through a list.
- [Trackers](https://www.shortsintel.com/docs/concepts/trackers): Standing watches on a creator or an Advertiser: how a cycle runs, when it reports a change, and how to pause one.

## Request samples

curl:

```bash
curl "https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/ads?status=all&media_type=video&hook_type=QUESTION&angle=PROBLEM_SOLUTION&offer_type=DISCOUNT&format=TALKING_HEAD&include=intelligence&limit=25" \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
```

TypeScript:

```typescript
const response = await fetch(
  "https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/ads?status=all&media_type=video&hook_type=QUESTION&angle=PROBLEM_SOLUTION&offer_type=DISCOUNT&format=TALKING_HEAD&include=intelligence&limit=25",
  {
    method: "GET",
    headers: {
      "Authorization": "Bearer sk_live_YOUR_KEY",
    },
  },
);

if (!response.ok) {
  throw new Error(`ShortsIntel ${response.status}`);
}

const data = await response.json();
```

Python:

```python
import requests

response = requests.get(
    "https://www.shortsintel.com/v1/trackers/trk_4b1e90c7aa/ads?status=all&media_type=video&hook_type=QUESTION&angle=PROBLEM_SOLUTION&offer_type=DISCOUNT&format=TALKING_HEAD&include=intelligence&limit=25",
    headers={
        "Authorization": "Bearer sk_live_YOUR_KEY",
    },
)
response.raise_for_status()

data = response.json()
```

200 · `{ items, next_cursor }`.

```json
{
  "items": [
    {
      "library": "meta",
      "id": "2233445566778899",
      "url": "https://www.facebook.com/ads/library/?id=2233445566778899",
      "advertiser": {
        "id": "100064000000001",
        "name": "Plunge"
      },
      "is_active": false,
      "first_shown": "2026-06-02T00:00:00.000Z",
      "last_shown": "2026-07-14T00:00:00.000Z",
      "placements": [
        "INSTAGRAM"
      ],
      "creative": {
        "title": "Three minutes. Every morning.",
        "body": "Our coldest tub yet, now in matte black.",
        "cta": "Learn More",
        "link_url": "https://plunge.example/black",
        "format": "IMAGE",
        "image_urls": [
          "https://cdn.shortsintel.com/ads/plunge-black.jpg"
        ],
        "video_urls": [],
        "thumbnail_urls": []
      },
      "reach": {
        "impressions": null,
        "spend": null,
        "currency": null,
        "audience": null
      },
      "kind": "commercial",
      "media_type": "image",
      "countries": [
        "US",
        "CA"
      ],
      "variant_count": 3,
      "days_running": 42,
      "archived": true,
      "stopped_at": "2026-07-14T00:00:00.000Z",
      "removed_from_library": true,
      "removed_at": "2026-09-20T08:00:00.000Z",
      "analysis": {
        "summary": "A matte black cold plunge tub shown in a bright bathroom.",
        "hook_type": null,
        "angle": "BENEFIT",
        "offer_type": "NONE",
        "format": "PRODUCT_SHOT"
      }
    }
  ],
  "next_cursor": "eyJzIjoiMjAyNi0wNi0wMlQwMDowMDowMC4wMDBaIiwibCI6IjEifQ"
}
```

[Previous Read a target's snapshots](https://www.shortsintel.com/docs/reference/trackers/list-tracker-snapshots)[Next List change reports](https://www.shortsintel.com/docs/reference/trackers/list-tracker-changes)
