openapi: 3.0.0
info:
  title: AudienceLab API
  version: 1.0.0
  description: API endpoints for AudienceLab

servers:
  - url: https://api.audiencelab.io
    description: Production API

tags:
  - name: Audience
  - name: Pixel
  - name: Enrichment

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key

  schemas:
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          example: "error message"

    PixelEvent:
      type: object
      properties:
        pixel_id:
          type: string
          example: "PIX123456"
        hem_sha256:
          type: string
          example: "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
        event_timestamp:
          type: string
          format: date-time
          example: "2024-01-15T10:30:00Z"
        event_type:
          type: string
          example: "page_view"
        ip_address:
          type: string
          example: "192.168.1.1"
        activity_start_date:
          type: string
          format: date-time
          example: "2024-01-15T00:00:00Z"
        activity_end_date:
          type: string
          format: date-time
          example: "2024-01-15T23:59:59Z"
        referrer_url:
          type: string
          example: "https://example.com/page"
        resolution:
          $ref: "#/components/schemas/PixelResolutionV3"
        event_data:
          type: object
          description: Additional event data

    PixelResolutionV3:
      type: object
      description: Resolution data containing enriched information for v3
      properties:
        UUID:
          type: string
          example: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
        FIRST_NAME:
          type: string
          example: "John"
        LAST_NAME:
          type: string
          example: "Doe"
        PERSONAL_ADDRESS:
          type: string
          example: "123 Main St"
        PERSONAL_CITY:
          type: string
          example: "San Francisco"
        PERSONAL_STATE:
          type: string
          example: "CA"
        PERSONAL_ZIP:
          type: string
          example: "94105"
        PERSONAL_ZIP4:
          type: string
          example: "1234"
        AGE_RANGE:
          type: string
          example: "25-34"
        CHILDREN:
          type: string
          example: "Yes"
        GENDER:
          type: string
          example: "Male"
        HOMEOWNER:
          type: string
          example: "Yes"
        MARRIED:
          type: string
          example: "No"
        NET_WORTH:
          type: string
          example: "$100K-$250K"
        INCOME_RANGE:
          type: string
          example: "$75K-$100K"
        DIRECT_NUMBER:
          type: string
          example: "+14155551234"
        DIRECT_NUMBER_DNC:
          type: string
          example: "No"
        MOBILE_PHONE:
          type: string
          example: "+14155555678"
        MOBILE_PHONE_DNC:
          type: string
          example: "No"
        PERSONAL_PHONE:
          type: string
          example: "+14155559012"
        PERSONAL_PHONE_DNC:
          type: string
          example: "No"
        BUSINESS_EMAIL:
          type: string
          example: "jdoe@acmecorp.com"
        PERSONAL_EMAILS:
          type: string
          example: "john.doe@email.com"
        PERSONAL_VERIFIED_EMAILS:
          type: string
          example: "john.doe@email.com"
        BUSINESS_VERIFIED_EMAILS:
          type: string
          example: "jdoe@acmecorp.com"
        SHA256_PERSONAL_EMAIL:
          type: string
          example: "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
        SHA256_BUSINESS_EMAIL:
          type: string
          example: "b665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae4"
        JOB_TITLE:
          type: string
          example: "Senior Software Engineer"
        HEADLINE:
          type: string
          example: "Building great software"
        DEPARTMENT:
          type: string
          example: "Engineering"
        SENIORITY_LEVEL:
          type: string
          example: "Senior"
        INFERRED_YEARS_EXPERIENCE:
          type: string
          example: "10"
        COMPANY_NAME_HISTORY:
          type: string
          example: "Previous Corp, Another Inc"
        JOB_TITLE_HISTORY:
          type: string
          example: "Software Engineer, Junior Developer"
        EDUCATION_HISTORY:
          type: string
          example: "Stanford University, BS Computer Science"
        COMPANY_ADDRESS:
          type: string
          example: "456 Business Ave"
        COMPANY_DESCRIPTION:
          type: string
          example: "Technology solutions provider"
        COMPANY_DOMAIN:
          type: string
          example: "acmecorp.com"
        COMPANY_EMPLOYEE_COUNT:
          type: string
          example: "100-500"
        COMPANY_LINKEDIN_URL:
          type: string
          example: "https://linkedin.com/company/acmecorp"
        COMPANY_NAME:
          type: string
          example: "Acme Corp"
        COMPANY_PHONE:
          type: string
          example: "+14155550000"
        COMPANY_REVENUE:
          type: string
          example: "$10M-$50M"
        COMPANY_SIC:
          type: string
          example: "7371"
        COMPANY_NAICS:
          type: string
          example: "541511"
        COMPANY_CITY:
          type: string
          example: "San Francisco"
        COMPANY_STATE:
          type: string
          example: "CA"
        COMPANY_ZIP:
          type: string
          example: "94107"
        COMPANY_INDUSTRY:
          type: string
          example: "Technology"
        LINKEDIN_URL:
          type: string
          example: "https://linkedin.com/in/johndoe"
        TWITTER_URL:
          type: string
          example: "https://twitter.com/johndoe"
        FACEBOOK_URL:
          type: string
          example: "https://facebook.com/johndoe"
        SOCIAL_CONNECTIONS:
          type: string
          example: "500+"
        SKILLS:
          type: string
          example: "Python, Go, JavaScript"
        INTERESTS:
          type: string
          example: "Technology, Startups"
        SKIPTRACE_MATCH_SCORE:
          type: integer
          nullable: true
          example: 95
        SKIPTRACE_NAME:
          type: string
          example: "John Doe"
        SKIPTRACE_ADDRESS:
          type: string
          example: "123 Main St"
        SKIPTRACE_CITY:
          type: string
          example: "San Francisco"
        SKIPTRACE_STATE:
          type: string
          example: "CA"
        SKIPTRACE_ZIP:
          type: string
          example: "94105"
        SKIPTRACE_LANDLINE_NUMBERS:
          type: string
          example: "+14155551111"
        SKIPTRACE_WIRELESS_NUMBERS:
          type: string
          example: "+14155552222"
        SKIPTRACE_CREDIT_RATING:
          type: string
          example: "Good"
        SKIPTRACE_DNC:
          type: string
          example: "No"
        SKIPTRACE_EXACT_AGE:
          type: string
          example: "32"
        SKIPTRACE_ETHNIC_CODE:
          type: string
          example: "A"
        SKIPTRACE_LANGUAGE_CODE:
          type: string
          example: "EN"
        SKIPTRACE_IP:
          type: string
          example: "192.168.1.1"
        SKIPTRACE_B2B_ADDRESS:
          type: string
          example: "456 Business Ave"
        SKIPTRACE_B2B_PHONE:
          type: string
          example: "+14155550000"
        SKIPTRACE_B2B_SOURCE:
          type: string
          example: "LinkedIn"
        SKIPTRACE_B2B_WEBSITE:
          type: string
          example: "https://acmecorp.com"
        VALID_PHONES:
          type: string
          example: "+14155551234,+14155555678"

    PixelFetchResponse:
      type: object
      properties:
        total_records:
          type: integer
          example: 500
        page_size:
          type: integer
          example: 100
        page:
          type: integer
          example: 1
        total_pages:
          type: integer
          example: 5
        events:
          type: array
          items:
            $ref: "#/components/schemas/PixelEvent"

    PixelEventV4:
      type: object
      properties:
        pixel_id:
          type: string
          example: "PIX123456"
        hem_sha256:
          type: string
          example: "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
        event_timestamp:
          type: string
          example: "2024-01-15"
        referrer_url:
          type: string
          example: "https://example.com/page"
        full_url:
          type: string
          description: Full URL extracted from event data
          example: "https://example.com/products/item-123"
        edid:
          type: string
          description: External Device ID (UUID from resolution)
          example: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
        resolution:
          $ref: "#/components/schemas/PixelResolutionV4"

    PixelResolutionV4:
      type: object
      description: Resolution data containing enrichment fields for v4 (UPPER_CASE keys)
      properties:
        FIRST_NAME:
          type: string
          example: "John"
        LAST_NAME:
          type: string
          example: "Doe"
        PERSONAL_ADDRESS:
          type: string
          example: "123 Main St"
        PERSONAL_CITY:
          type: string
          example: "San Francisco"
        PERSONAL_STATE:
          type: string
          example: "CA"
        PERSONAL_ZIP:
          type: string
          example: "94105"
        PERSONAL_ZIP4:
          type: string
          example: "1234"
        AGE_RANGE:
          type: string
          example: "25-34"
        CHILDREN:
          type: string
          example: "Yes"
        GENDER:
          type: string
          example: "Male"
        HOMEOWNER:
          type: string
          example: "Yes"
        MARRIED:
          type: string
          example: "No"
        NET_WORTH:
          type: string
          example: "$100K-$250K"
        INCOME_RANGE:
          type: string
          example: "$75K-$100K"
        ALL_LANDLINES:
          type: string
          example: "+14155551234"
        LANDLINE_DNC:
          type: string
          example: "No"
        ALL_MOBILES:
          type: string
          example: "+14155555678"
        MOBILE_DNC:
          type: string
          example: "No"
        PERSONAL_EMAILS:
          type: string
          example: "john.doe@email.com"
        PERSONAL_VERIFIED_EMAILS:
          type: string
          example: "john.doe@email.com"
        SHA256_PERSONAL_EMAIL:
          type: string
          example: "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
        COMPANY_NAME:
          type: string
          example: "Acme Corp"
        COMPANY_DESCRIPTION:
          type: string
          example: "Technology solutions provider"
        COMPANY_EMPLOYEE_COUNT:
          type: string
          example: "100-500"
        COMPANY_DOMAIN:
          type: string
          example: "acmecorp.com"
        COMPANY_ADDRESS:
          type: string
          example: "456 Business Ave"
        COMPANY_CITY:
          type: string
          example: "San Francisco"
        COMPANY_STATE:
          type: string
          example: "CA"
        COMPANY_ZIP:
          type: string
          example: "94107"
        COMPANY_PHONE:
          type: string
          example: "+14155550000"
        COMPANY_REVENUE:
          type: string
          example: "$10M-$50M"
        COMPANY_SIC:
          type: string
          example: "7371"
        COMPANY_NAICS:
          type: string
          example: "541511"
        COMPANY_INDUSTRY:
          type: string
          example: "Technology"
        BUSINESS_EMAIL:
          type: string
          example: "jdoe@acmecorp.com"
        BUSINESS_VERIFIED_EMAILS:
          type: string
          example: "jdoe@acmecorp.com"
        SHA256_BUSINESS_EMAIL:
          type: string
          example: "b665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae4"
        JOB_TITLE:
          type: string
          example: "Senior Software Engineer"
        HEADLINE:
          type: string
          example: "Building great software"
        DEPARTMENT:
          type: string
          example: "Engineering"
        SENIORITY_LEVEL:
          type: string
          example: "Senior"
        INFERRED_YEARS_EXPERIENCE:
          type: string
          example: "10"
        COMPANY_NAME_HISTORY:
          type: string
          example: "Previous Corp, Another Inc"
        JOB_TITLE_HISTORY:
          type: string
          example: "Software Engineer, Junior Developer"
        EDUCATION_HISTORY:
          type: string
          example: "Stanford University, BS Computer Science"
        COMPANY_LINKEDIN_URL:
          type: string
          example: "https://linkedin.com/company/acmecorp"
        INDIVIDUAL_LINKEDIN_URL:
          type: string
          example: "https://linkedin.com/in/johndoe"
        INDIVIDUAL_TWITTER_URL:
          type: string
          example: "https://twitter.com/johndoe"
        INDIVIDUAL_FACEBOOK_URL:
          type: string
          example: "https://facebook.com/johndoe"
        SKILLS:
          type: string
          example: "Python, Go, JavaScript"
        INTERESTS:
          type: string
          example: "Technology, Startups"

    PixelFetchResponseV4:
      type: object
      properties:
        total_records:
          type: integer
          example: 500
        page_size:
          type: integer
          example: 100
        page:
          type: integer
          example: 1
        total_pages:
          type: integer
          example: 5
        events:
          type: array
          items:
            $ref: "#/components/schemas/PixelEventV4"

    AudienceCreateRequest:
      type: object
      properties:
        name:
          type: string
        filters:
          $ref: "#/components/schemas/AudienceFilters"
        segment:
          type: array
          description: |
            Optional list of audience segment IDs. Use the **full exact ID including its prefix**
            in the current taxonomy nomenclature:
            - `b2c_<number>` — consumer (B2C) segments, e.g. `b2c_1254`
            - `b2b_<number>` — business (B2B) segments, e.g. `b2b_1042`

            Pass the complete ID with its prefix. Bare numbers (`1253`) and the legacy
            Delivr format (`al_XXXXXX`) are **not** supported.
          items:
            type: string
          example: ["b2c_1253"]
        days_back:
          type: integer
      required:
        - name
        - filters

    AudienceCreateResponse:
      type: object
      properties:
        audienceId:
          type: string
          example: "812b78c3-83e6-4d6a-8245-def0dde26223"

    AudienceFilters:
      type: object
      description: Filter criteria for audience selection. All array fields must be passed as arrays even for single values.
      properties:
        age:
          type: object
          description: Age range filter
          properties:
            minAge:
              type: integer
              description: Minimum age
              example: 25
            maxAge:
              type: integer
              description: Maximum age
              example: 45
        city:
          type: array
          description: List of cities to filter by
          items:
            type: string
        state:
          type: array
          description: List of states to filter by, skiptrace history (use abbreviations like CA, NY)
          items:
            type: string
        personalState:
          type: array
          description: List of states to filter by, current residence (use abbreviations like CA, NY)
          items:
            type: string
        zip:
          type: array
          description: List of ZIP codes to filter by
          items:
            type: string
        gender:
          type: array
          description: List of genders to filter by (M=Male, F=Female, U=Unknown)
          items:
            type: string
            enum:
              - M
              - F
              - U
        businessProfile:
          type: object
          description: Business profile filters
          properties:
            industry:
              type: array
              description: List of industries
              items:
                type: string
            seniority:
              type: array
              description: List of seniority levels
              items:
                type: string
            companyName:
              type: array
              description: List of company names
              items:
                type: string
            jobTitle:
              type: array
              description: List of job titles to include
              items:
                type: string
            excludeJobTitle:
              type: array
              description: List of job titles to exclude. Records with these job titles will be removed from results, but records with no job title value will still be included.
              items:
                type: string
        attributes:
          type: object
          description: Personal attributes filters
          properties:
            education:
              type: array
              description: |
                List of education levels to include.
                Accepted values: "high school", "bachelor's", "master's", "doctorate"
              items:
                type: string
                enum: ["high school", "bachelor's", "master's", "doctorate"]
              example: ["bachelor's", "master's"]
            excludeEducation:
              type: array
              description: |
                List of education levels to exclude. Records with these education levels will be removed from results, but records with no education value will still be included.
                Accepted values: "high school", "bachelor's", "master's", "doctorate"
              items:
                type: string
                enum: ["high school", "bachelor's", "master's", "doctorate"]
              example: ["high school"]

    AudiencePreviewRequest:
      type: object
      properties:
        filters:
          $ref: "#/components/schemas/AudienceFilters"
        segment:
          type: array
          description: |
            Optional list of audience segment IDs. Use the **full exact ID including its prefix**
            in the current taxonomy nomenclature:
            - `b2c_<number>` — consumer (B2C) segments, e.g. `b2c_1253`
            - `b2b_<number>` — business (B2B) segments, e.g. `b2b_1042`

            Pass the complete ID with its prefix. Bare numbers (`1253`) and the legacy
            Delivr format (`al_XXXXXX`) are **not** supported.
          items:
            type: string
          example: ["b2c_1253"]
        days_back:
          type: integer
          description: Number of days back to search
        score:
          type: array
          items:
            type: string
          description: Optional scores to filter by (low, medium, high)

    AudiencePreviewResponse:
      type: object
      properties:
        count:
          type: integer
          description: Total number of records matching the criteria
          example: 140
        field_coverage:
          type: object
          description: Percentage of matching records that have each field populated, computed over the full dataset
          additionalProperties:
            type: number
            format: double
          example:
            first_name: 0.95
            last_name: 0.94
            company: 0.62
            company_domain: 0.58
            job_title: 0.41
            b2b_email: 0.33
            b2b_phone: 0.29
            personal_email: 0.71
            valid_phones: 0.44
        result:
          type: array
          description: A sample list of enriched profiles matching the criteria
          items:
            type: object
            additionalProperties:
              type: string
          example:
            - company: "Acme Corp"
              first_name: "John"
              last_name: "Doe"
              b2b_email: "jdoe@example.com"
              sha256: "46f7b9bf9b2d7c35bd900490b2b8d4d4210e9f32ed117b5b688391e1dc85f053"

    EnrichCreateRequest:
      type: object
      properties:
        name:
          type: string
          example: "Prospect Upload"
        operator:
          type: string
          enum: ["AND", "OR"]
          default: "OR"
          example: "OR"
        columns:
          type: array
          items:
            type: string
          description: |
            Optional explicit list of fields included in each record.

            **Accepted values**

            - `EMAIL`
            - `PERSONAL_EMAIL`
            - `BUSINESS_EMAIL`
            - `FIRST_NAME`
            - `LAST_NAME`
            - `PHONE`
            - `PERSONAL_ADDRESS`
            - `PERSONAL_CITY`
            - `PERSONAL_STATE`
            - `PERSONAL_ZIP`
            - `COMPANY_NAME`
            - `COMPANY_DOMAIN`
            - `COMPANY_INDUSTRY`
            - `SHA256_PERSONAL_EMAIL`
            - `LINKEDIN_URL`
            - `UP_ID`
            - `JOB_TITLE`
          example: ["EMAIL", "FIRST_NAME", "LAST_NAME", "PHONE"]
        records:
          type: array
          items:
            type: object
            additionalProperties:
              type: string
          example:
            - first_name: "Ava"
              last_name: "Stone"
              phone: "+12145550123"
              email: "ava.stone@example.com"
            - first_name: "Noah"
              last_name: "Reed"
              phone: "+18305559876"
              email: "noah.reed@example.com"
      required:
        - name
        - records
    EnrichCreateResponse:
      type: object
      properties:
        jobId:
          type: string
          example: "399e88c3-3263-4d9a-826c-437ef57f7b6c"
        status:
          type: string
          example: "IN_QUEUE"

    PixelCreateRequest:
      type: object
      properties:
        websiteName:
          type: string
          description: The display name for the pixel (site name)
        websiteUrl:
          type: string
          description: The URL where the pixel will be installed
        webhookUrl:
          type: string
          nullable: true
          description: Optional webhook URL for pixel events
      required:
        - websiteName
        - websiteUrl
      example:
        websiteName: "Test Site"
        websiteUrl: "https://test.com"
        webhookUrl: "https://hooks.example.com/pixel"

    PixelCreateResponse:
      type: object
      properties:
        pixel_id:
          type: string
          example: "912b78c3-83e6-4d6a-8245-def0dde26224"
        install_url:
          type: string
          example: "https://pixel.example/install/abcd1234"

    AttributesResponse:
      type: object
      properties:
        data:
          type: object
          additionalProperties:
            type: object
            properties:
              data:
                type: array
                items:
                  type: string
              count:
                type: integer
      example:
        data:
          sic:
            data: ["7371", "7372"]
            count: 2
          gender:
            data: ["male", "female"]
            count: 2

    CreateCustomIntentRequest:
      type: object
      properties:
        topic:
          type: string
          description: The custom topic name
        description:
          type: string
          description: Description of the custom topic
      required:
        - topic
        - description
      example:
        topic: "Custom Interest"
        description: "Users interested in custom topic"

    CreateCustomIntentResponse:
      type: object
      properties:
        status:
          type: string
          example: "processing"

    EnrichSearchRequest:
      type: object
      properties:
        request_id:
          type: string
          description: Optional request ID for tracking
          example: "req_123456"
        filter:
          type: object
          description: |
            Search filter parameters with field names as keys and single string values.

            Available fields:

            **Personal Information:**
            - `uuid` - Unique identifier
            - `first_name` - First name
            - `last_name` - Last name
            - `email` - Email address
            - `email_domain` - Email domain
            - `sha256_email` - SHA256 hash of email
            - `phone` - Phone number

            **Location Information:**
            - `personal_zip` - Personal ZIP/postal code
            - `personal_address` - Personal street address
            - `personal_state` - Personal state/province
            - `personal_city` - Personal city

            **Company Information:**
            - `company_name` - Company name
            - `company_domain` - Company domain name

            **Social/Professional:**
            - `linkedin_url` - LinkedIn profile URL

          additionalProperties:
            type: string
          example:
            first_name: "John"
            last_name: "Doe"
            email: "user@example.com"
            phone: "555-123-4567"
            company_name: "Nike"
            personal_city: "San Francisco"
            company_domain: "nike.com"
        fields:
          type: array
          description: |
            Optional array of field names to include in the response. If not specified, all available fields are returned.

            **Available output fields:**
            - `company` - Company name
            - `job_title` - Job title/position
            - `first_name` - First name
            - `last_name` - Last name
            - `b2b_email` - Business email address
            - `personal_email` - Personal email address
            - `b2b_phone` - Business phone number
            - `personal_phone` - Personal phone number
            - `sha256` - SHA256 hash identifier
            - `linkedin_url` - LinkedIn profile URL
            - `address` - Street address
            - `city` - City
            - `state` - State/province
            - `zip` - ZIP/postal code
            - `industry` - Industry classification
            - `company_domain` - Company domain
          items:
            type: string
            enum:
              - company
              - job_title
              - first_name
              - last_name
              - b2b_email
              - personal_email
              - b2b_phone
              - personal_phone
              - sha256
              - linkedin_url
              - address
              - city
              - state
              - zip
              - industry
              - company_domain
          example:
            ["first_name", "last_name", "b2b_email", "company", "job_title"]
        is_or_match:
          type: boolean
          description: |
            Determines how multiple criteria are combined:
            - `true`: OR logic - returns contacts matching ANY of the criteria
            - `false`: AND logic - returns contacts matching ALL of the criteria
          example: false
      required:
        - filter
        - is_or_match

    EnrichSearchResponse:
      type: object
      properties:
        request_id:
          type: string
          description: Request ID if provided in the request
          example: "req_123456"
        timestamp:
          type: integer
          format: int64
          description: Unix timestamp in milliseconds
          example: 1704067200000
        found:
          type: integer
          description: Number of matching records found
          example: 2
        result:
          type: array
          items:
            type: object
            description: Enriched contact data containing all available fields for the matched records
          description: Array of enriched contact records with complete profile information
          example:
            - email: "john.doe@example.com"
              first_name: "John"
              last_name: "Doe"
              business_email: "jdoe@acmecorp.com"
              sha256_email: "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
              company_name: "Acme Corp"
              company_domain: "acmecorp.com"
              job_title: "Senior Software Engineer"
              industry: "Technology"
              city: "San Francisco"
              state: "CA"
              zip: "94105"
              address: "123 Market St"
              linkedin_url: "https://linkedin.com/in/johndoe"
            - email: "jane.smith@example.com"
              first_name: "Jane"
              last_name: "Smith"
              business_email: "jsmith@acmecorp.com"
              sha256_email: "b665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae4"
              company_name: "Acme Corp"
              company_domain: "acmecorp.com"
              job_title: "Product Manager"
              industry: "Technology"
              city: "New York"
              state: "NY"
              zip: "10001"
              address: "456 Broadway"
              linkedin_url: "https://linkedin.com/in/janesmith"

security:
  - ApiKeyAuth: []

paths:
  # Audience-related endpoints
  /audiences:
    post:
      tags:
        - Audience
      summary: Create Audience
      description: |
        Create an audience from filters and/or segment IDs.

        Segment IDs must be passed as the **full exact ID with prefix** in the current
        taxonomy nomenclature (`b2c_<number>` or `b2b_<number>`, e.g. `b2c_1253`).
        The legacy Delivr format (`al_XXXXXX`) and bare numbers are no longer supported.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AudienceCreateRequest"
      responses:
        "200":
          description: Audience created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AudienceCreateResponse"
        "400":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    get:
      tags:
        - Audience
      summary: Get Audiences
      security:
        - ApiKeyAuth: []
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number (1-indexed)
          example: 1
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: Number of items per page (max 1000)
          example: 100
      responses:
        "200":
          description: Successfully retrieved audiences list
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_records:
                    type: integer
                    example: 50
                  page_size:
                    type: integer
                    example: 100
                  page:
                    type: integer
                    example: 1
                  total_pages:
                    type: integer
                    example: 1
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          example: "aa1a0c14-2dff-4389-b025-06a308df9ee9"
                        name:
                          type: string
                          example: "My Test Audience"
                        next_scheduled_refresh:
                          type: string
                          nullable: true
                          example: null
                        scheduled_refresh:
                          type: boolean
                          example: false
                        refresh_interval:
                          type: integer
                          nullable: true
                          example: null
                        webhook_url:
                          type: string
                          nullable: true
                          example: null
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /audiences/preview:
    post:
      tags:
        - Audience
      summary: Preview Audience
      description: |
        Preview the results and count of an audience based on filters before creating it.

        Segment IDs must be passed as the **full exact ID with prefix** in the current
        taxonomy nomenclature (`b2c_<number>` or `b2b_<number>`, e.g. `b2c_1253`).
        The legacy Delivr format (`al_XXXXXX`) and bare numbers are no longer supported.
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AudiencePreviewRequest"
      responses:
        "200":
          description: Successful preview
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AudiencePreviewResponse"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /audiences/custom:
    post:
      tags:
        - Audience
      summary: Create Custom Audience
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCustomIntentRequest"
      responses:
        "201":
          description: Custom intent created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateCustomIntentResponse"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /enrich:
    post:
      tags:
        - Enrichment
      summary: Enrich contact
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EnrichSearchRequest"
            examples:
              company_search:
                summary: Search by company name
                value:
                  request_id: "req_123456"
                  filter:
                    company_name: "Nike"
                  is_or_match: false
              email_search:
                summary: Search by email
                value:
                  request_id: "req_789012"
                  filter:
                    email: "john.doe@example.com"
                  is_or_match: false
              phone_search:
                summary: Search by phone number
                value:
                  request_id: "req_345678"
                  filter:
                    phone: "555-123-4567"
                  is_or_match: false
              combined_search:
                summary: Combined search with multiple filters (AND logic)
                value:
                  request_id: "req_multi_001"
                  filter:
                    company_name: "Tesla"
                    personal_state: "CA"
                    first_name: "John"
                  is_or_match: false
              or_search:
                summary: Search with OR logic
                value:
                  request_id: "req_or_001"
                  filter:
                    company_name: "Google"
                    personal_city: "San Francisco"
                  is_or_match: true
              search_with_fields:
                summary: Search with specific fields in response
                value:
                  request_id: "req_fields_001"
                  filter:
                    company_name: "Apple"
                  is_or_match: false
                  fields:
                    [
                      "first_name",
                      "last_name",
                      "b2b_email",
                      "company",
                      "job_title",
                    ]
      responses:
        "200":
          description: Successfully retrieved enriched contact data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EnrichSearchResponse"
        "400":
          description: Bad request - Invalid query parameters
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - Missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /enrichments:
    get:
      tags:
        - Enrichment
      summary: Get Enrichments
      description: Retrieve a paginated list of enrichment jobs for the authenticated account
      security:
        - ApiKeyAuth: []
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number (1-indexed)
          example: 1
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: Number of items per page (max 1000)
          example: 100
      responses:
        "200":
          description: Successfully retrieved enrichments list
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_records:
                    type: integer
                    example: 150
                  page_size:
                    type: integer
                    example: 100
                  page:
                    type: integer
                    example: 1
                  total_pages:
                    type: integer
                    example: 2
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          example: "ca80f27b-9ae8-4351-99ac-51d5b5ebe423"
                        name:
                          type: string
                          example: "1761687181"
                        status:
                          type: string
                          example: "IN_QUEUE"
                        csv_url:
                          type: string
                          nullable: true
                          example: "gs://bucket/path/to/file.csv.gz"
                        total:
                          type: integer
                          nullable: true
                          example: 1500
                        created_at:
                          type: string
                          format: date-time
                          example: "2025-10-29T10:30:00Z"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
    post:
      tags:
        - Enrichment
      summary: Create Enrichment Job
      description: |
        Upload enrichment records and enqueue a job for processing.

        **Supported fields**

        - `EMAIL`
        - `PERSONAL_EMAIL`
        - `BUSINESS_EMAIL`
        - `FIRST_NAME`
        - `LAST_NAME`
        - `PHONE`
        - `PERSONAL_ADDRESS`
        - `PERSONAL_CITY`
        - `PERSONAL_STATE`
        - `PERSONAL_ZIP`
        - `COMPANY_NAME`
        - `COMPANY_DOMAIN`
        - `COMPANY_INDUSTRY`
        - `SHA256_PERSONAL_EMAIL`
        - `LINKEDIN_URL`
        - `UP_ID`
        - `JOB_TITLE`
      security:
        - ApiKeyAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EnrichCreateRequest"
            example:
              name: "Sample Upload"
              operator: "OR"
              columns: ["EMAIL", "FIRST_NAME", "LAST_NAME", "PHONE"]
              records:
                - first_name: "Harper"
                  last_name: "Nguyen"
                  phone: "+12145550123"
                  email: "harper.nguyen@example.com"
                - first_name: "Liam"
                  last_name: "Carter"
                  phone: "+18305550987"
                  email: "liam.carter@example.com"
      x-codeSamples:
        - lang: cURL
          label: Create enrichment job
          source: |
            curl -X POST https://api.example.com/enrichments \
              -H "Content-Type: application/json" \
              -H "X-API-Key: YOUR_API_KEY" \
              -d '{
                    "name": "Sample Upload",
                    "operator": "OR",
                    "columns": ["EMAIL", "FIRST_NAME", "LAST_NAME", "PHONE"],
                    "records": [
                      {
                        "first_name": "Harper",
                        "last_name": "Nguyen",
                        "phone": "+12145550123",
                        "email": "harper.nguyen@example.com"
                      },
                      {
                        "first_name": "Liam",
                        "last_name": "Carter",
                        "phone": "+18305550987",
                        "email": "liam.carter@example.com"
                      }
                    ]
                  }'
      responses:
        "202":
          description: Enrichment job accepted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EnrichCreateResponse"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /audiences/{id}:
    get:
      tags:
        - Audience
      summary: Audience lookup
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: The UUID of the audience to fetch
          example: "aa1a0c14-2dff-4389-b025-06a308df9ee9"
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number (1-indexed)
          example: 1
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: Number of items per page (max 1000)
          example: 100
      responses:
        "200":
          description: Successfully retrieved audience data
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_records:
                    type: integer
                    example: 500
                  page_size:
                    type: integer
                    example: 100
                  page:
                    type: integer
                    example: 1
                  total_pages:
                    type: integer
                    example: 5
                  data:
                    type: array
                    items:
                      type: object
                      additionalProperties:
                        type: string
                      description: CSV row data as key-value pairs
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Audience not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "NOT_FOUND"

    delete:
      tags:
        - Audience
      summary: Audience delete
      parameters:
        - name: audience_id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Audience deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "success"
                  message:
                    type: string
                    example: "audience deleted"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /audiences/attributes/{attribute}:
    get:
      tags:
        - Audience
      summary: Audience Attributes
      parameters:
        - name: attribute
          in: path
          required: true
          schema:
            type: string
            enum: [sic, industries, departments, seniority, gender, segments]
            description: The specific attribute key. Available options are sic, industries, departments, seniority, gender, segments
      responses:
        "200":
          description: Successful response with data for the specified attribute
          content:
            application/json:
              schema:
                type: object
                properties:
                  attributes:
                    type: object
                    additionalProperties:
                      type: object
                      properties:
                        data:
                          type: array
                          items:
                            oneOf:
                              - type: string
                              - type: object
                        count:
                          type: integer
              example:
                attributes:
                  sic:
                    data: ["7371", "7372"]
                    count: 2
        "404":
          description: Attribute not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: "Attribute not found"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  # Pixel-related endpoints
  /pixels:
    post:
      tags:
        - Pixel
      summary: Create Pixel
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PixelCreateRequest"
      responses:
        "201":
          description: Pixel created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PixelCreateResponse"
        "400":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

    get:
      tags:
        - Pixel
      summary: Get Pixels
      security:
        - ApiKeyAuth: []
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number (1-indexed)
          example: 1
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: Number of items per page (max 1000)
          example: 100
      responses:
        "200":
          description: Successfully retrieved pixels list
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_records:
                    type: integer
                    example: 10
                  page_size:
                    type: integer
                    example: 100
                  page:
                    type: integer
                    example: 1
                  total_pages:
                    type: integer
                    example: 1
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          example: "003daacb-d261-421c-9781-311df9c381d8"
                        provider:
                          type: string
                          enum: ["v3", "v4"]
                          example: "v4"
                        install_url:
                          type: string
                          description: Installation URL derived from provider data
                          example: "https://cdn.example.com/p.js"
                        website_name:
                          type: string
                          example: "Marketing Campaign Pixel"
                        website_url:
                          type: string
                          example: "https://example.com"
                        webhook_url:
                          type: string
                          nullable: true
                          example: null
                        last_sync_status:
                          type: string
                          nullable: true
                        last_sync_count:
                          type: integer
                          nullable: true
                        last_error_message:
                          type: string
                          nullable: true
                        last_sync_start:
                          type: string
                          nullable: true
                        last_sync_end:
                          type: string
                          nullable: true
                        last_sync_duration:
                          type: string
                          nullable: true
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /pixels/{id}:
    get:
      tags:
        - Pixel
      summary: Pixel lookup
      description: Retrieves pixel events. Auto-detects the pixel provider and returns V3 (PixelFetchResponse) or V4 (PixelFetchResponseV4) format accordingly.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: The UUID of the pixel to fetch events for
          example: "003daacb-d261-421c-9781-311df9c381d8"
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number (1-indexed)
          example: 1
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: Number of items per page (max 1000)
          example: 100
      responses:
        "200":
          description: Successfully retrieved pixel events. Returns V3 or V4 format based on the pixel's provider.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/PixelFetchResponse"
                  - $ref: "#/components/schemas/PixelFetchResponseV4"
        "400":
          description: Bad request - invalid parameters or pixel missing
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Forbidden - pixel does not belong to the authenticated account
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Not found - pixel does not exist
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /pixels/{id}/v4:
    get:
      tags:
        - Pixel
      summary: Pixel lookup (V4)
      description: Retrieves pixel events (V4 format)
      security:
        - ApiKeyAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: The UUID of the pixel to fetch events for
          example: "003daacb-d261-421c-9781-311df9c381d8"
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number (1-indexed)
          example: 1
        - name: page_size
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 1000
            default: 100
          description: Number of items per page (max 1000)
          example: 100
      responses:
        "200":
          description: Successfully retrieved pixel events (V4 format)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PixelFetchResponseV4"
        "400":
          description: Bad request - invalid parameters or pixel missing
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Unauthorized - missing or invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Forbidden - pixel does not belong to the authenticated account
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Not found - pixel does not exist
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /pixels/{pixel_id}:
    delete:
      tags:
        - Pixel
      summary: Pixel delete
      security:
        - ApiKeyAuth: []
      parameters:
        - name: pixel_id
          in: path
          required: true
          schema:
            type: string
          description: The UUID of the pixel to delete
          example: "003daacb-d261-421c-9781-311df9c381d8"
      responses:
        "200":
          description: Pixel deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "success"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Pixel not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
