openapi: 3.0.0
info:
  title: LinkedIn Ad Library Ad Details API
  description: |
    Retrieve a single ad's detail page from LinkedIn's Ad Library, including the creative, the advertiser, and (for ads served in the EU) the DSA transparency data: run dates, estimated impressions, impressions by country, and ad targeting.

    Get an `ad_id` from the `linkedin_ad_library` engine: ads whose `link` points at an `/ad-library/detail/` page carry it as `id`. Employer-brand ads link to a different page this engine cannot fetch.

    **Transparency data is not available for every ad.** LinkedIn publishes the run dates, impressions, and targeting block only for ads delivered in the EU. For any other ad the response contains the creative and the "About the ad" fields only, and `first_shown_date`, `last_shown_date`, `total_impressions`, `total_impressions_min`, `total_impressions_max`, `impressions_by_country`, `targeting`, and `targeting_parameters` are all omitted.
  version: 1.0.0
servers:
  - url: https://www.searchapi.io/api/v1
paths:
  /search:
    get:
      summary: LinkedIn Ad Library Ad Details
      security:
        - ApiKeyAuth: []
        - ApiKeyQuery: []
      parameters:
        - name: engine
          in: query
          required: true
          description: Set to `linkedin_ad_library_ad_details` for LinkedIn Ad Library ad details
          schema:
            type: string
            default: "linkedin_ad_library_ad_details"
            enum: ["linkedin_ad_library_ad_details"]
        - name: ad_id
          in: query
          required: true
          description: The numeric LinkedIn ad ID, e.g. `870198506`. Returned as `id` by the `linkedin_ad_library` engine for ads whose `link` points at an `/ad-library/detail/` page (employer-brand ads use a different page this engine cannot fetch).
          schema:
            type: string
            pattern: '^\d+$'
      responses:
        '200':
          description: Successful response. A dead or invalid `ad_id` is also a `200`; the response then carries a top-level `error` message and no `ad` object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Validation Error. There is an issue with query parameters, such as missing required parameters or invalid values.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication Error. The API key is missing or invalid.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate Limit Exceeded. The number of allowed requests has been exceeded. Consider upgrading your plan or waiting for the limit to reset.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Server Error. Internal server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Timeout. The page could not be fetched from LinkedIn in time.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: 'Use Bearer authentication. Format: "Bearer YOUR_API_KEY"'
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api_key
      description: Pass API key as query parameter
  schemas:
    SearchResponse:
      type: object
      properties:
        search_metadata:
          $ref: '#/components/schemas/SearchMetadata'
        search_parameters:
          $ref: '#/components/schemas/SearchParameters'
        ad:
          $ref: '#/components/schemas/Ad'
        error:
          type: string
          description: Error message returned when the ad is no longer available or the `ad_id` is invalid
    SearchMetadata:
      type: object
      required: [id, status, created_at]
      properties:
        id:
          type: string
          description: "Unique identifier for the search request"
        status:
          type: string
          description: "Status of the search request"
        created_at:
          type: string
          format: date-time
          description: "Timestamp when the search was created"
        request_time_taken:
          type: number
          description: "Time taken to make the request in seconds"
        parsing_time_taken:
          type: number
          description: "Time taken to parse the results in seconds"
        total_time_taken:
          type: number
          description: "Total time taken for the search in seconds"
        request_url:
          type: string
          description: "LinkedIn Ad Library URL for this ad"
        html_url:
          type: string
          description: "URL to view HTML results"
        json_url:
          type: string
          description: "URL to view JSON results"
    SearchParameters:
      type: object
      properties:
        engine:
          type: string
          description: Search engine used
        ad_id:
          type: string
          description: Ad ID requested
    Ad:
      type: object
      required: [id, link, ad_type, ad_format, advertiser, content]
      properties:
        id:
          type: string
          description: The ad ID, echoing the requested `ad_id`
        link:
          type: string
          description: URL of the ad detail page on LinkedIn Ad Library
        external_link:
          type: string
          description: URL the ad's creative links to, as served by LinkedIn (including its `trk` tracking parameter). Omitted when the creative carries no click-through.
        ad_type:
          type: string
          description: Type of the ad, using the same vocabulary as the `linkedin_ad_library` engine
          enum: ["image", "video", "carousel", "multi_image", "event", "document", "article", "message", "job", "text"]
        ad_format:
          type: string
          description: 'LinkedIn''s own label for the ad format, e.g. `Single Image Ad`, `Video Ad`, `Carousel Ad`, `Spotlight Ad`, `Job Ad`, `Message Ad`'
        advertiser:
          $ref: '#/components/schemas/Advertiser'
        content:
          $ref: '#/components/schemas/AdContent'
        paid_for_by:
          type: string
          description: Entity that paid for the ad, as disclosed by LinkedIn. Omitted for `job` ads, which LinkedIn publishes without a payer.
        first_shown_date:
          type: string
          format: date
          description: 'First day the ad ran, in YYYY-MM-DD. EU-served ads only.'
        last_shown_date:
          type: string
          format: date
          description: 'Last day the ad ran, in YYYY-MM-DD. EU-served ads only.'
        total_impressions:
          type: string
          description: 'Estimated total impressions as a range, e.g. `20k-30k` or `< 1k`. EU-served ads only.'
        total_impressions_min:
          type: integer
          description: 'Lower bound of `total_impressions` as a number, e.g. `20000`. Omitted for open-ended ranges such as `< 1k`.'
        total_impressions_max:
          type: integer
          description: 'Upper bound of `total_impressions` as a number, e.g. `30000`.'
        impressions_by_country:
          type: array
          description: 'Share of impressions per country, ordered by share. EU-served ads only, and LinkedIn states this data may take up to 48 hours to appear, so a recent ad can report `total_impressions` without a breakdown.'
          items:
            $ref: '#/components/schemas/CountryImpressions'
        targeting:
          type: array
          description: 'Targeting parameters chosen by the advertiser, e.g. Language and Location. EU-served ads only.'
          items:
            $ref: '#/components/schemas/TargetingSegment'
        targeting_parameters:
          type: array
          description: 'Which broad targeting categories the advertiser used. EU-served ads only.'
          items:
            $ref: '#/components/schemas/TargetingParameter'
    Advertiser:
      type: object
      required: [name]
      properties:
        name:
          type: string
          description: Name of the advertiser
        link:
          type: string
          description: URL of the advertiser's LinkedIn page. Omitted for ads published from a member profile that LinkedIn shows without a link.
        position:
          type: string
          description: 'Headline of the member who published the ad. Present for ads posted from a member profile.'
        promotor:
          type: string
          description: 'Organization the ad is promoted by, when it differs from the publishing member.'
        thumbnail:
          type: string
          description: URL of the advertiser's profile image
    AdContent:
      type: object
      description: Ad creative content. Available fields depend on the `ad_type`.
      properties:
        headline:
          type: string
          description: Full commentary text of the ad, with its paragraph breaks preserved as blank lines
        headline_links:
          type: array
          description: URLs of links found in the headline text
          items:
            type: string
        image:
          type: string
          description: 'URL of the main media image, the cover image for `video` ad types, or the cover of an `article`. Omitted when LinkedIn serves the creative without one.'
        cta:
          type: string
          description: 'Headline of the creative''s link card (LinkedIn''s Headline field). Present for `image` and `video` ad types.'
        call_to_action:
          type: string
          description: 'Label of the ad''s call-to-action button, e.g. `Learn more` or `View event`. Omitted when the creative renders no button.'
        description:
          type: string
          description: 'Description text. Present for `image`, `video`, `article`, and `job` ad types.'
        video_link:
          type: string
          description: 'URL of the highest-bitrate mp4 rendition. Present for `video` ad type.'
        videos:
          type: array
          description: 'All mp4 renditions of the video, highest bitrate first. Present for `video` ad type.'
          items:
            $ref: '#/components/schemas/VideoRendition'
        items:
          type: array
          description: 'Carousel cards, or the photos of a multi-photo post. Present for `carousel` and `multi_image` ad types.'
          items:
            $ref: '#/components/schemas/CarouselItem'
        title:
          type: string
          description: 'Title of the document or article. Present for `document` and `article` ad types.'
        pages:
          type: array
          description: 'URLs of the document page preview images. Present for `document` ad type.'
          items:
            type: string
        total_pages:
          type: integer
          description: 'Number of pages in the full document. Present for `document` ad type.'
        time:
          type: string
          description: 'Date and time of the event. Present for `event` ad type.'
        name:
          type: string
          description: 'Name of the event. Present for `event` ad type.'
        organizer:
          type: string
          description: 'Organizer of the event. Present for `event` ad type.'
        location:
          type: string
          description: 'Location of the event. Present for `event` ad type.'
        user:
          type: string
          description: 'Name of the message sender. Present for `message` ad type.'
        user_thumbnail:
          type: string
          description: 'URL of the message sender''s profile photo. Present for `message` ad type.'
        text:
          type: string
          description: 'Text of the sponsored message, with paragraphs separated by blank lines. Present for `message` ad type.'
    VideoRendition:
      type: object
      required: [link]
      properties:
        link:
          type: string
          description: URL of the mp4 file
        type:
          type: string
          description: 'MIME type, e.g. `video/mp4`'
        bitrate:
          type: integer
          description: Bitrate of the rendition in bits per second
    CarouselItem:
      type: object
      required: [image]
      properties:
        image:
          type: string
          description: URL of the carousel card image
        cta:
          type: string
          description: Title text of the carousel card
        link:
          type: string
          description: URL the carousel card links to. Omitted for `multi_image` posts and carousel layouts whose cards are not linked.
    CountryImpressions:
      type: object
      required: [country, percentage_display]
      properties:
        country:
          type: string
          description: Country name as shown by LinkedIn
        percentage:
          type: integer
          description: 'Share of impressions in percent, as reported by LinkedIn. Omitted for rows LinkedIn shows as `< 1%`; `percentage_display` still carries them.'
        percentage_display:
          type: string
          description: 'Share exactly as displayed by LinkedIn, e.g. `87%` or `< 1%`'
    TargetingSegment:
      type: object
      required: [name]
      properties:
        name:
          type: string
          description: 'Name of the targeting parameter, e.g. `Language` or `Location`'
        included:
          type: array
          description: Segments the advertiser targeted
          items:
            type: string
        excluded:
          type: array
          description: Segments the advertiser excluded
          items:
            type: string
    TargetingParameter:
      type: object
      required: [name, is_targeted, is_excluded]
      properties:
        name:
          type: string
          description: 'Targeting category, e.g. `Audience`, `Demographic`, `Company`, `Education`, `Job`, `Member Interests and Traits`'
        is_targeted:
          type: boolean
          description: Whether the advertiser used this category to target
        is_excluded:
          type: boolean
          description: Whether the advertiser used this category to exclude
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: string
          description: Error message describing what went wrong
