# The Ad record

> Every platform's ads come back in one shape, with the same keys, ISO dates and ranges. What a platform does not have is `null`, never a missing key.

Base URL: `https://api.publicadsapi.com` · Auth: `authorization: Bearer <key>` · Web version: https://publicadsapi.com/docs/api/ad-record

Ad (a Meta ad):

```json
{
  "id": "meta_900000000000001",
  "platform": "meta",
  "platform_ad_id": "900000000000001",
  "library_url": "https://www.facebook.com/ads/library/?id=900000000000001",
  "advertiser": {
    "id": "100000000000001",
    "name": "Northwind Running Co",
    "domain": null,
    "library_url": "https://www.facebook.com/ads/library/?view_all_page_id=100000000000001"
  },
  "status": "active",
  "first_shown": "2026-08-04T07:00:00Z",
  "last_shown": "2026-10-18T07:00:00Z",
  "format": "image",
  "text": {
    "headline": "Trail shoes, half price this week",
    "body": "Grip that holds on wet rock. Free returns for 60 days.",
    "description": null,
    "cta": "Shop now"
  },
  "text_source": "platform",
  "link_url": "https://northwind-running.example/trail",
  "media": [
    {
      "type": "image",
      "url": "https://example.com/sandbox-media/meta-trail.jpg",
      "preview_url": null,
      "width": 1080,
      "height": 1080
    }
  ],
  "placements": [
    "facebook",
    "instagram",
    "audience_network",
    "messenger"
  ],
  "regions": null,
  "metrics": {
    "impressions": null,
    "reach": null,
    "spend": null
  },
  "variants": 1
}
```

## Fields

| Field | Type | What it is |
| --- | --- | --- |
| id | string | Ours, unique across platforms: `<platform>_<the platform's id>`, e.g. `meta_900000000000001`. Google's carries the advertiser too: `google_<AR id>_<CR id>`. |
| platform | string | `meta`, `google`, `tiktok` or `linkedin`. |
| platform_ad_id | string | The platform's own id for the ad (Google's creative id, `CR…`). |
| library_url | string | The ad's page in the platform's library. |
| advertiser.id | string or null | A Meta page id, Google's `AR…` id, TikTok's business id or LinkedIn's company id: pass it back to that platform's search. |
| advertiser.name | string or null | As the platform shows it. |
| advertiser.domain | string or null | The advertiser's domain, where the platform gives one (Google's verified domain). |
| advertiser.library_url | string or null | The advertiser's page in the platform's library. |
| status | string | `active`, `inactive`, or `unknown` where the platform does not say (Google, TikTok, LinkedIn). |
| first_shown, last_shown | string or null | ISO 8601 in UTC: the first and last days the platform says the ad was shown. |
| format | string | `text`, `image`, `video`, `carousel`, `dynamic` (catalogue ads) or `unknown`. |
| text.headline, text.body, text.description, text.cta | string or null | The ad's words. `headline` is Meta's title, Google's and LinkedIn's headline, TikTok's title. |
| text_source | string | `platform`, or `ocr` where the text was read from the ad's image (Google text ads). |
| link_url | string or null | Where the ad sends people. |
| media[] | array | `type` (`image` or `video`), `url`, `preview_url` (a still for a video), `width`, `height`. |
| placements | array of strings | Where on the platform it ran, e.g. `facebook`, `instagram`, `search`, `youtube`. |
| regions | array of strings or null | ISO 3166 alpha-2 codes of the countries it ran in, where the platform says. |
| metrics.impressions, metrics.reach | range or null | `{ "min", "max" }`, as the platform gives a range: TikTok's "1K-10K" is 1000 and 10000. |
| metrics.spend | range or null | `{ "min", "max", "currency" }`, ISO 4217 currency. Political and issue ads on Meta. |
| variants | integer or null | How many versions of the ad the platform groups under it, where it says. |
| raw | any | Only with `include=raw`: the platform's own record. |

## Nulls and empty lists

Every key is always there. A value the platform doesn't give is `null` (a single value or object) or `[]` (a list where none is the answer, such as `media` for a text ad). `null` means the platform doesn't say, never zero.

## Media addresses expire

`media[].url` and `preview_url` are the platform's own addresses, as its library serves them. They expire, Meta's within days, so download the files you want to keep when you get them. We don't host copies.

## Ids

`id` is stable: the same ad has the same `id` in every search, so you can store it and spot ads you have seen before. Pass it to `GET /v1/ads/{id}` for the detail. `platform_ad_id` is the platform's own, for its library's links.

## The platform's own record

`include=raw` adds `raw` to each ad: the platform's record as we read it, for anything we don't map. Its shape is the platform's and can change without notice; the rest of the record doesn't.

## Detail

`GET /v1/ads/{id}` returns this record plus `detail`: versions, countries, targeting, EU reach and payer. See [One ad](https://publicadsapi.com/docs/api/ads.md).

See also: [One ad](https://publicadsapi.com/docs/api/ads.md) · [Errors](https://publicadsapi.com/docs/errors.md)
