---
title: "Get the notable campaigns across watched brands"
method: GET
path: "/v1/email/competitive/watchlist/notable"
tags: ["email-competitive"]
---

# Get the notable campaigns across watched brands

`GET /v1/email/competitive/watchlist/notable`

## Request

- Base URL: `https://us1.platform.bird.com`
- URL: `https://us1.platform.bird.com/v1/email/competitive/watchlist/notable`
- Auth: one of:
  - HTTP bearer
  - API key in cookie `bird_session`

Returns the campaigns worth a second look across every brand the workspace watches,
surfaced for what they did rather than for when they were sent.

Each campaign carries the signal that surfaced it: an unusually big send for its brand,
a campaign read unusually well for its brand, or heavy spam placement at one mailbox
provider. Every signal compares a campaign against its own brand's history, never
against your other brands, so several brands can carry the same signal in one period.

Up to 100 findings are returned. Selection takes turns across brands in watchlist order
until the response is full, prioritizing spam placement, biggest sends, then read-rate
standouts within a brand. Returned findings retain watchlist, signal, domain, and source
order. Your own sending is never included.

An empty list is an ordinary answer, not a failure: a signal only fires on a campaign
that stands out for its own brand, and a watchlist of steady senders produces nothing.
Check `panel_status` to tell that apart from the panel being unreachable.

This is a separate request from the watchlist on purpose, so a slow or degraded panel
read cannot delay the watchlist itself.

## Query parameters

- `range` 7 | 30 | 90

## Headers

- `X-Workspace-Id` string
- `X-Organization-Id` string

## Response `200`

The notable campaigns for the period.

- EmailCompetitiveNotableFeed: Campaigns worth a second look across the brands a workspace watches.
  - `period` EmailCompetitivePeriod, required: The period the response describes. Most reports resolve a rolling window when requested; send-time and notable reports can carry the panel's own window. These bounds describe coverage, not a guarantee of measurement freshness.
    - `days` integer, required: Length of the period in days.
    - `from` string, date-time, required: Start of the period, inclusive.
    - `to` string, date-time, required: End of the period, exclusive. Daily figures therefore run through the previous whole UTC day and never include the one in progress.
  - `panel_status` 'ok' | 'not_in_panel' | 'no_data' | 'unavailable', required: Whether panel figures are available for a row, and when they are not, why. `ok` means the panel reported figures for the requested period. `not_in_panel` means the panel does not track the sending domain at all, which is common for smaller and newer senders. `no_data` means the panel tracks the domain but observed no mail from it in the period. `unavailable` means the figures could not be retrieved this time and the same request may well succeed on a retry.
  - `data` EmailCompetitiveNotableCampaign[], required: Up to 100 campaigns selected across watched brands. Selection takes turns across brands in watchlist order until the response is full, prioritizing spam placement, biggest sends, then read-rate standouts within each brand. Within one signal, rows compare the matching spam rate, volume ratio, or read rate descending; missing values sort last and ties retain tracked-domain and source order. Selected rows are returned in watchlist order, then biggest-send, read-rate, and spam signal order, followed by tracked-domain and source order. One campaign may appear once per signal because each row carries different evidence. Empty when nothing qualified; check `panel_status` to distinguish that from an unavailable panel.
    - `watchlist_brand_id` string, required
    - `brand_name` string, required: The brand's name.
    - `signal` string, required: Why this campaign was surfaced. The set is open and grows as new signals are added. Every signal describes the campaign against its own brand's history, never against the other brands you watch, so several brands can carry the same signal in one period and none of them is the top of anything. `biggest_send` is a send far above that brand's own median: unusual for the brand, not merely large. `read_rate_standout` is a campaign read unusually well for its brand. `landing_in_spam` is one heavily filed as spam at a single mailbox provider, named in `mailbox_provider`, which is worth seeing even when the brand's overall placement looks healthy.
    - `claim` EmailCompetitiveNotableClaim, required: What the panel itself asserts about a campaign, in its own words. Present only on the campaigns the panel chose to make a claim about, which is a minority of them: a campaign can be surfaced as notable without the panel putting a headline on it, and that is an ordinary outcome rather than missing data.
      - `text` string, required: The panel's own phrasing, which may name the window the claim was measured over ("Biggest send in 7 days") or not ("Best-read campaign"). Show it as written rather than rebuilding it from the signal, and do not parse a window out of it.
    - `evidence` EmailCompetitiveNotableEvidence, required: The figures behind a campaign's signal, for ordering or filtering the list yourself. Which field carries a value depends on the signal, and each is null both on the signals it does not describe and on a campaign of its own signal the panel published no figure for.
      - `ratio_to_median` number, nullable, required: How many times the brand's own median volume this send was. A value of 29 means the send was twenty-nine times the brand's typical volume for the period. Null on every signal other than `biggest_send`, and on a `biggest_send` campaign the panel published no ratio for.
      - `read_rate_observations` integer, nullable, required: How many panel observations `campaign.read_rate` was measured over. A rate over thirty observations and one over a hundred and forty are not equally worth showing, and this is what separates them. Null on every signal other than `read_rate_standout`, and on a `read_rate_standout` campaign the panel published no denominator for.
      - `mailbox_provider_spam_rate` number, nullable, required: Share of this campaign filed as spam at the one provider named in `mailbox_provider`, as a value between 0 and 1. A different measurement from the campaign's overall `spam_rate`, and the one this signal is about. Null on every signal other than `landing_in_spam`, and on a `landing_in_spam` campaign whose provider counts the panel did not publish, so a spam entry can arrive without the rate behind it.
      - `mailbox_provider_observations` integer, nullable, required: How many observations at that provider `mailbox_provider_spam_rate` was measured over. Null on the same terms.
    - `mailbox_provider` string, required: A mailbox provider, as the email panel identifies it. A lowercase identifier rather than a display name, so pick your own label for it, and treat the set as open: the panel reports whichever providers it observed, and `gmail`, `hotmail`, `yahoo`, `aol` and `comcast` are the ones it returns most. Apple never appears, because the panel does not measure it, so a surface offering an Apple row has no measurement behind it. The panel's buckets are not the same as the ones the [mailbox-provider stats breakdown](/docs/api/reference/get-email-stats-by-mailbox-provider) reports: Microsoft's properties appear here as `hotmail` rather than `microsoft`, and Apple is absent, so the two are not a joinable dimension.
    - `campaign` EmailCompetitiveCampaign, required: The most recent campaign observed for a brand in the period.
      - `id` string, required: The identifier for this campaign. Use it to fetch this one campaign on its own. It is a string, and it needs to stay one. The values are long enough that JavaScript, and any other language that stores every number as a floating point value, will round them, and a rounded identifier matches no campaign at all. Compare it and pass it back as text.
      - `subject` string, required: The subject line the panel saw on this campaign.
      - `sent_at` string, date-time, required: When the panel first saw this campaign arrive.
      - `image_url` string, uri, nullable, required: Where the panel's capture of the rendered email can be fetched, null when it captured none. Panels image only some of what they observe, so an absent creative is an ordinary outcome rather than a failed one. The image is served from the panel's own host rather than from ours, so a page embedding it has to allow that host.
      - `reach` integer, nullable, required: Estimated recipients this campaign reached, null when the panel observed the campaign but published no estimate for it.
      - `read_rate` number, nullable, required: Estimated share of recipients who read this campaign, null when the panel published no rate for it. Panel read rates count dwell time, so they do not move with the automatic opens that inflate a sender's own open rate.
      - `has_creative` boolean, required: Whether the panel captured the rendered email for this campaign.
      - `discount_percent` number, nullable, required: The first recognized percentage-discount offer in the subject, null when none is recognized. Does not detect dollar discounts, free shipping or offers revealed only inside the email.
      - `inbox_rate` number, nullable, required: Share of this campaign that reached an inbox, null when the panel observed it without recording where it landed. It describes this send rather than the brand's domain, so a single bad campaign is visible against a brand whose overall placement still looks healthy.
      - `spam_rate` number, nullable, required: Share of this campaign that was filed as spam, null on the same terms.
  - `truncated` boolean, required: Whether Bird omitted eligible panel findings to keep this response to 100 rows. False does not promise that the panel observed every qualifying campaign in the period.

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `403`: Insufficient permissions
- `404`: Resource not found
- `422`: The request has invalid field values, violates a business rule, or carries a query parameter the endpoint does not declare. Field validation errors use `type: validation_error` and include the affected fields in `details`. Business-rule errors identify the failed rule in `type`.
- `429`: Rate limit exceeded
- `500`: Internal server error
- `503`: The service is temporarily unavailable. If `Retry-After` is present, wait for that delay before retrying; otherwise, retry with exponential backoff. Reuse the same idempotency key and request when retrying a mutation.

---

[API](https://skmtc.dev/messagebird/apis/bird-api.md) · [All operations](https://skmtc.dev/messagebird/apis/bird-api/llms.txt) · [OpenAPI document](https://skmtc.dev/messagebird/apis/bird-api/revisions/6dfce1179799?raw)
