> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stophy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Meta Ads meta Ads Search API

> Scrape ads from the Meta ad library. Call the Meta Ads meta Ads Search API and get JSON back in one request. 1 credit per call. Failed calls cost nothing.

Scrape ads from the Meta ad library.

## Request

`query` is required.

<CodeGroup>
  ```typescript TypeScript icon="https://mintcdn.com/sirathic/7E4w9-IC4ysabjfc/images/icons/typescript.svg?fit=max&auto=format&n=7E4w9-IC4ysabjfc&q=85&s=d8272a85e64145620f1fbbfcf7932986" theme={null}
  import { Stophy } from "stophy";

  const stophy = new Stophy({ apiKey: process.env.STOPHY_API_KEY });
  const result = await stophy.meta.ads.search({ query: "nike", platforms: ["instagram"], language: "en" });
  console.log(result.data.results);
  ```

  ```python Python icon="python" theme={null}
  from stophy import Stophy

  stophy = Stophy()  # reads STOPHY_API_KEY
  result = stophy.meta.ads.search(query="nike", platforms=["instagram"], language="en")
  print(result["data"]["results"])
  ```

  ```bash cURL icon="terminal" theme={null}
  curl -X POST https://api.stophy.dev/v1/meta/ads/search \
    -H "Authorization: Bearer $STOPHY_API_KEY" \
    -H "content-type: application/json" \
    -d '{"query":"nike","platforms":["instagram"],"language":"en"}'
  ```

  ```bash CLI icon="square-terminal" theme={null}
  stophy meta ads search nike --platforms instagram --language en
  ```
</CodeGroup>

## Response

If successful, the response body contains the standard envelope. `data.results[]` contains the ads that match, each with its page, text, format and platforms.

The following example is a real response, truncated: each list shows one item and long strings are cut.

```json theme={null}
{
  "success": true,
  "data": {
    "results": [
      {
        "adId": "925321173274919",
        "adUrl": "https://www.facebook.com/ads/library/?id=925321173274919",
        "pageId": "89516513179",
        "pageName": "Nordstrom Rack",
        "pageUrl": "https://facebook.com/NordstromRack",
        "pageAvatarUrl": "https://scontent-mia5-1.xx.fbcdn.net/v/t39.35426-6/764807066_1529917005842224_1129201910993892893_n.jpg?stp=dst-jpg_s60…",
        "pageCategories": ["Clothing (Brand)"],
        "pageLikes": 2518828,
        "isActive": true,
        "firstShownAt": "2026-08-03T07:00:00.000Z",
        "platforms": ["facebook", "instagram"],
        "format": "video",
        "text": "Buy online and pick up in store for free! Get up to 70% off Nike, Vince, Madewell, adidas and more.",
        "linkUrl": "https://fb.com/canvas_doc/1072291375736811",
        "linkTitle": "Fast & Free Pickup",
        "linkDescription": "Fast & Free Pickup",
        "ctaText": "Learn more",
        "videoUrls": ["https://video-mia5-1.xx.fbcdn.net/o1/v/t2/f2/m366/AQPMHFeiZ7eLWAaUSfl9UjSZ2QaJHkx2VTZvZtGQn2Lri3AqZsR0B4SYnzTlS8BwXd3tu…"],
        "versions": 2,
        "countries": ["US"]
      }
    ],
    "cursor": "AQHTwHM-vkpydSiDv773CcWZ17K3G0tZFLBXM2TO_cva3F8YzTvrI9ZkLpDUZtrHRCPc"
  },
  "creditsUsed": 1,
  "requestId": "2fe9dbad-fc48-4890-9751-0b24b596035b"
}
```

| Field | Type | Description |
| - | - | - |
| `cursor` | string | The pagination token. Pass it as `cursor` to retrieve the next page. Omitted on the last page. |
| `firstShownAt` | string (ISO 8601) | The first day the ad was shown. |
| `countries` | string\[] | Countries the Ad Library says the ad ran in. Meta sends none for most ads, so an empty list means unknown, not worldwide. It is not the country you searched. |

For every field, see the response schema on this page.

## Optional parameters

| Parameter | Type | Description |
| - | - | - |
| `country` | string | The country to query, as a two-letter ISO 3166-1 code, or `all`. If unset, defaults to `us`. |
| `status` | string | Active ads, inactive ads or both. Acceptable values are `active`, `inactive` and `all`. If unset, defaults to `active`. |
| `mediaType` | string | Restricts results to ads of this type. `text` means no image or video. Acceptable values are `image`, `video` and `text`. |
| `platforms` | string\[] | Restricts results to ads shown on at least one of these platforms. Acceptable values are `facebook`, `instagram`, `audienceNetwork`, `messenger`, `whatsapp` and `threads`. |
| `language` | string | Restricts results to ads written in this language. Two-letter code, such as `en`. |
| `shownFrom` | string (date) | Restricts results to ads shown on or after this day. Format: `YYYY-MM-DD`. |
| `shownTo` | string (date) | Restricts results to ads shown on or before this day. Format: `YYYY-MM-DD`. |
| `cursor` | string | The pagination token from the previous response. |

## Billing

Each successful request consumes 1 credit, regardless of the number of items returned. Requests that fail, or that return no items, are not billed.

## Pagination

Results are paginated. To retrieve the next page, pass the value of `data.cursor` as `cursor` in a subsequent request. A response that omits `cursor` is the last page.

## Related methods

* [Meta ads by page](/api-reference/endpoint/meta-ads-page): Accepts an ad's `pageId` as `advertiser`. Scrape the ads a Facebook page runs.
* [Meta ad details](/api-reference/endpoint/meta-ads-ad): Accepts `adUrl`. Scrape a Meta ad's details.


## OpenAPI

````yaml api-reference/openapi.json POST /v1/meta/ads/search
openapi: 3.1.0
info:
  title: Stophy API
  version: '1'
  description: >-
    Every endpoint is a POST that takes its input as a JSON object body. Unknown
    fields are rejected with 400.


    Responses leave out empty values: null, empty strings, empty objects and
    empty nested lists are not sent.


    Text comes back whole. To get shorter responses, add
    ?maxTextLength=<characters> to the URL. Every text value longer than that is
    cut and ends with …. A screenshot is never cut, and a page whose text was
    cut has isTruncated set to true.


    x-credits is what one call costs. Every call costs the same, whatever it
    returns, unless an operation's description says it costs per 10 results, or
    per second of audio. Then x-credits is the lowest price and x-credits-max
    the most one call can cost. Where an operation takes limit, send it to
    return fewer results and pay for fewer.


    When a response has a cursor, send it back unchanged with the same input to
    get the next page. When it has a page, send the next page number.
servers:
  - url: https://api.stophy.dev
security:
  - apiKey: []
paths:
  /v1/meta/ads/search:
    post:
      summary: Scrape ads from the Meta ad library
      description: Costs 1 credit per call. Pages with cursor.
      operationId: metaAdsSearch
      parameters:
        - $ref: '#/components/parameters/MaxTextLength'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                query:
                  type: string
                  minLength: 1
                  maxLength: 200
                  description: >-
                    Words to find in the ad. Several words match as one exact
                    phrase.
                country:
                  default: us
                  pattern: ^(?:[A-Za-z]{2}|[Aa][Ll][Ll])$
                  description: >-
                    ISO 3166-1 alpha-2 country code, or all. Any case is
                    accepted.
                  type: string
                status:
                  default: active
                  type: string
                  enum:
                    - active
                    - inactive
                    - all
                mediaType:
                  description: >-
                    The Ad Library's own Media type filter: image, video, or
                    text (no image or video).
                  type: string
                  enum:
                    - image
                    - video
                    - text
                platforms:
                  description: >-
                    The Ad Library's own Platform filter: only ads shown on at
                    least one of these platforms.
                  minItems: 1
                  type: array
                  items:
                    type: string
                    enum:
                      - facebook
                      - instagram
                      - audienceNetwork
                      - messenger
                      - whatsapp
                      - threads
                language:
                  description: >-
                    The Ad Library's own Language filter: a two-letter code like
                    en. Only ads written in this language.
                  type: string
                  pattern: ^[A-Za-z]{2}$
                shownFrom:
                  description: >-
                    The Ad Library's own Impressions by date: ads shown on or
                    after this day.
                  type: string
                  format: date
                  pattern: >-
                    ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$
                shownTo:
                  description: >-
                    The Ad Library's own Impressions by date: ads shown on or
                    before this day.
                  type: string
                  format: date
                  pattern: >-
                    ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$
                cursor:
                  type: string
                  minLength: 1
                  description: The cursor from the previous response. Send it as is.
              required:
                - query
              additionalProperties: false
            example:
              query: nike
              platforms:
                - instagram
              language: en
      responses:
        '200':
          description: The data, and the credits this call used.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/RequestId'
            x-credits-used:
              $ref: '#/components/headers/CreditsUsed'
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            x-cache:
              $ref: '#/components/headers/Cache'
            x-cache-age:
              $ref: '#/components/headers/CacheAge'
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                  - creditsUsed
                  - requestId
                properties:
                  success:
                    const: true
                  data:
                    type: object
                    additionalProperties: false
                    properties:
                      results:
                        type: array
                        items:
                          type: object
                          additionalProperties: false
                          properties:
                            adId:
                              type: string
                            adUrl:
                              type: string
                              format: uri
                            pageId:
                              type: string
                            pageName:
                              type: string
                            pageUrl:
                              type: string
                              format: uri
                            pageAvatarUrl:
                              type: string
                              format: uri
                            pageCategories:
                              type: array
                              items:
                                type: string
                            pageLikes:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            isActive:
                              type: boolean
                            firstShownAt:
                              type: string
                              format: date-time
                              pattern: >-
                                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                            lastShownAt:
                              type: string
                              format: date-time
                              pattern: >-
                                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                            platforms:
                              type: array
                              items:
                                type: string
                            format:
                              type: string
                            text:
                              type: string
                            linkUrl:
                              type: string
                              format: uri
                            linkTitle:
                              type: string
                            linkDescription:
                              type: string
                            ctaText:
                              type: string
                            imageUrls:
                              type: array
                              items:
                                type: string
                                format: uri
                            videoUrls:
                              type: array
                              items:
                                type: string
                                format: uri
                            cards:
                              type: array
                              items:
                                type: object
                                additionalProperties: false
                                properties:
                                  text:
                                    type: string
                                  linkUrl:
                                    type: string
                                    format: uri
                                  linkTitle:
                                    type: string
                                  ctaText:
                                    type: string
                                  imageUrl:
                                    type: string
                                    format: uri
                                  videoUrl:
                                    type: string
                                    format: uri
                                required: []
                            versions:
                              description: >-
                                How many copies of this creative the Ad Library
                                groups together. Meta sends it on one ad of each
                                group, so other ads of the group and ad details
                                give null.
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            categories:
                              type: array
                              items:
                                type: string
                            paidBy:
                              type: string
                            spendMin:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            spendMax:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            spendCurrency:
                              type: string
                              pattern: ^[A-Z]{3}$
                              description: ISO 4217 currency code, e.g. USD.
                            impressionsMin:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            impressionsMax:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            reachMin:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            reachMax:
                              type: integer
                              minimum: -9007199254740991
                              maximum: 9007199254740991
                            countries:
                              type: array
                              items:
                                type: string
                              description: >-
                                Countries the Ad Library says the ad ran in.
                                Meta sends none for most ads, so an empty list
                                means unknown, not worldwide. It is not the
                                country you searched.
                          required:
                            - adUrl
                            - isActive
                      cursor:
                        type: string
                    required:
                      - results
                  creditsUsed:
                    type: integer
                  requestId:
                    type: string
        4XX:
          $ref: '#/components/responses/Error'
        5XX:
          $ref: '#/components/responses/Error'
components:
  parameters:
    MaxTextLength:
      name: maxTextLength
      in: query
      required: false
      description: >-
        Cut every text value in the response to this many characters. A value
        that was cut ends with …, and a page whose text was cut has isTruncated
        set to true. A screenshot is never cut. Leave it out to get the full
        text.
      schema:
        type: integer
        minimum: 1
  headers:
    RequestId:
      description: The request id. Quote it when you report a problem.
      schema:
        type: string
    CreditsUsed:
      description: Credits this call used.
      schema:
        type: integer
    RateLimitLimit:
      description: Requests allowed in the current window.
      schema:
        type: integer
    RateLimitRemaining:
      description: Requests left in the current window.
      schema:
        type: integer
    RateLimitReset:
      description: Unix time in seconds when the current window resets.
      schema:
        type: integer
    Cache:
      description: hit if this result came from the cache, miss if it was fetched live.
      schema:
        type: string
    CacheAge:
      description: Seconds since the returned result was written to the cache.
      schema:
        type: integer
    RetryAfter:
      description: Seconds to wait before retrying.
      schema:
        type: integer
  responses:
    Error:
      description: The request failed. retryable says whether trying again can help.
      headers:
        X-Request-ID:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Error:
      type: object
      required:
        - success
        - error
      properties:
        success:
          const: false
        error:
          type: object
          required:
            - code
            - message
            - retryable
            - requestId
          properties:
            code:
              type: string
              enum:
                - cliSessionCompleted
                - cliSessionExists
                - cliSessionNotFound
                - forbidden
                - insufficientCredits
                - internalError
                - inviteClaimed
                - inviteDisabled
                - inviteExpired
                - inviteUsedUp
                - invalidCliSession
                - invalidCliVerifier
                - invalidRequest
                - notFound
                - rateLimited
                - sourceChanged
                - sourceRefused
                - sourceTimeout
                - sourceUnavailable
                - tooManyInFlight
                - unauthorized
                - unsupportedMediaType
            message:
              type: string
            retryable:
              type: boolean
            retryAfterSeconds:
              type: integer
            requestId:
              type: string
            requiredCredits:
              type: number
            availableCredits:
              type: number
            billingUrl:
              type: string
              const: https://stophy.dev/billing
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.