openapi: 3.1.0
info:
  title: CEOInterviews API
  description: |
    The world's largest database of verified executive conversation transcripts.
    Access 1,000,000+ quotes and transcripts from 20,000+ C-suite leaders across
    the S&P 500, NASDAQ, and global markets.

    All transcripts are AI and human-verified for speaker authenticity.
  version: "1.0.0"
  contact:
    name: CEOInterviews Support
    url: https://ceointerviews.ai/support/
  termsOfService: https://ceointerviews.ai/terms_of_service/

servers:
  - url: https://ceointerviews.ai
    description: Production

security:
  - ApiKeyAuth: []

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key obtained from your CEOInterviews API Settings dashboard.

  schemas:
    CompanyNested:
      type: object
      properties:
        id:
          type: integer
          description: Unique company identifier
        ticker:
          type: string
          description: Stock ticker symbol
          example: AAPL
        full_name:
          type: string
          description: Full company name
          example: Apple Inc.
        logo_url:
          type: string
          format: uri
          description: URL to company logo
        is_snp500:
          type: boolean
        is_nasdaq:
          type: boolean
        is_snp1500:
          type: boolean
        is_nasdaq100:
          type: boolean
        is_ai_startup:
          type: boolean
        is_top_startup:
          type: boolean
        is_usa_based:
          type: boolean
        is_china_based:
          type: boolean
        is_europe_based:
          type: boolean

    Entity:
      type: object
      properties:
        id:
          type: integer
          description: Unique entity identifier
        name:
          type: string
          description: Full name of the executive
          example: Tim Cook
        simple_name:
          type: string
          description: Normalized/simplified name
        title:
          type: string
          description: Job title
          example: CEO
        institution:
          type: string
          description: Current organization
          example: Apple Inc.
        description:
          type: string
          description: Brief biography
        gender:
          type: string
          enum: [M, F, O]
        is_top_influencer:
          type: boolean
        is_politician:
          type: boolean
        is_company_leader:
          type: boolean
        profile_pic_url:
          type: string
          format: uri
        company:
          $ref: '#/components/schemas/CompanyNested'

    Company:
      type: object
      properties:
        company_id:
          type: integer
          description: Unique company identifier
        name:
          type: string
          description: Full company name
        ticker:
          type: string
          description: Stock ticker symbol
        normalized_name:
          type: string
          description: Simplified company name (without Inc., Corp., etc.)
        logo_url:
          type: string
          format: uri
        is_snp500:
          type: boolean
        is_nasdaq:
          type: boolean
        is_snp1500:
          type: boolean
        is_nasdaq100:
          type: boolean
        is_ai_startup:
          type: boolean
        is_top_startup:
          type: boolean
        is_usa_based:
          type: boolean
        is_china_based:
          type: boolean
        is_europe_based:
          type: boolean

    FeedItemExtra:
      type: object
      properties:
        duration_secs:
          type: integer
          description: Video duration in seconds
        channel_name:
          type: string
          description: Source channel name
        view_count:
          type: integer
          description: Number of views (when available)

    FeedItem:
      type: object
      properties:
        feed_item_id:
          type: integer
          description: Unique feed item identifier
        source_url:
          type: string
          format: uri
          description: Original source URL (e.g. YouTube link)
        entity_id:
          type: integer
        entity_name:
          type: string
        entity_title:
          type: string
        institution:
          type: string
        is_politician:
          type: boolean
        is_company_leader:
          type: boolean
        item_title:
          type: string
          description: Title of the media content
        publish_date:
          type: string
          format: date-time
          description: Publication date (ISO 8601)
        head_image:
          type: string
          format: uri
          description: Thumbnail or header image URL
        head_image_type:
          type: string
          enum: [video, image]
        entity_img:
          type: string
          format: uri
        thumbnail_image_url:
          type: string
          format: uri
        share_link:
          type: string
          format: uri
          description: Shareable link to the content on CEOInterviews
        transcript:
          type: string
          description: Full transcript text
        quotes:
          type: array
          items:
            type: object
          description: Quotes extracted from this content
        extra:
          $ref: '#/components/schemas/FeedItemExtra'
        company_id:
          type: integer
        appearance_date_v2:
          type: string
          description: Date of actual appearance (may differ from publish date)
        is_deleted_on_source:
          type: boolean

    QuoteEntity:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        simple_name:
          type: string
        title:
          type: string
        institution:
          type: string
        profile_pic_url:
          type: string
          format: uri
        is_politician:
          type: boolean
        is_company_leader:
          type: boolean
        company:
          type: object
          properties:
            id:
              type: integer
            ticker:
              type: string
            full_name:
              type: string
            logo_url:
              type: string
              format: uri

    QuoteFeedItem:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        source_url:
          type: string
          format: uri
        source_created_at:
          type: string
          format: date-time
        thumbnail_url:
          type: string
          format: uri

    Quote:
      type: object
      properties:
        id:
          type: integer
          description: Unique quote identifier
        text:
          type: string
          description: The quote text content
        source_url:
          type: string
          format: uri
        source_title:
          type: string
        is_notable:
          type: boolean
          description: Flagged as a notable/important quote
        is_controversial:
          type: boolean
          description: Flagged as controversial
        is_financial_policy:
          type: boolean
          description: Related to financial or policy matters
        topics:
          type: array
          items:
            type: string
          description: Topic tags
        entities:
          type: array
          items:
            type: string
          description: Mentioned entity names
        companies:
          type: array
          items:
            type: string
          description: Mentioned company names
        created_at:
          type: string
          format: date-time
        timestamp_from_tx:
          type: string
          description: Timestamp within the original media
        entity:
          $ref: '#/components/schemas/QuoteEntity'
        feed_item:
          $ref: '#/components/schemas/QuoteFeedItem'

    Error:
      type: object
      properties:
        error:
          type: string

paths:
  /api/get_entities/:
    get:
      operationId: getEntities
      summary: Search executives and notable figures
      description: |
        Search and filter the database of 20,000+ tracked executives, CEOs,
        politicians, and influential leaders. Supports keyword search by name
        and filtering by company attributes (index membership, geography, etc.).
      parameters:
        - name: keyword
          in: query
          schema:
            type: string
          description: >
            Fuzzy search across executive name, title, company name, and stock ticker.
            Supports partial names, tickers, titles, and multi-term queries in any order.
            Examples: "Tim Cook", "Elon", "AAPL", "CEO Tesla", "devinder kumar amd"
        - name: gender
          in: query
          schema:
            type: string
            enum: [M, F, O]
          description: Filter by gender
        - name: company_id
          in: query
          schema:
            type: integer
          description: Filter by associated company ID
        - name: is_snp500
          in: query
          schema:
            type: boolean
          description: Filter for S&P 500 company executives
        - name: is_nasdaq
          in: query
          schema:
            type: boolean
          description: Filter for NASDAQ company executives
        - name: is_snp1500
          in: query
          schema:
            type: boolean
          description: Filter for S&P 1500 company executives
        - name: is_nasdaq100
          in: query
          schema:
            type: boolean
          description: Filter for NASDAQ 100 company executives
        - name: is_ai_startup
          in: query
          schema:
            type: boolean
          description: Filter for AI startup executives
        - name: is_top_startup
          in: query
          schema:
            type: boolean
          description: Filter for top startup executives
        - name: is_usa_based
          in: query
          schema:
            type: boolean
          description: Filter for US-based company executives
        - name: is_china_based
          in: query
          schema:
            type: boolean
          description: Filter for China-based company executives
        - name: is_europe_based
          in: query
          schema:
            type: boolean
          description: Filter for Europe-based company executives
        - name: is_public_company
          in: query
          schema:
            type: boolean
          description: Filter for public company executives only
        - name: page_num
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
          description: Page number for pagination
        - name: page_size
          in: query
          schema:
            type: integer
            default: 10
            minimum: 1
            maximum: 500
          description: Results per page (max 500)
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/Entity'
                  page_has_previous:
                    type: boolean
                  page_has_next:
                    type: boolean
                  page_num:
                    type: integer
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Monthly API quota exceeded (500,000 requests/month)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/get_feed/:
    get:
      operationId: getFeed
      summary: Get executive interview transcripts and media appearances
      description: |
        Retrieve verified transcripts from executive media appearances including interviews, podcasts, earnings calls, and conferences. Filter by executive, company, keyword, and date range. Keyword search requires an entity or company filter.
      parameters:
        - name: entity_id
          in: query
          schema:
            type: integer
          description: Filter by specific entity ID
        - name: entity_name
          in: query
          schema:
            type: string
          description: Filter by entity name (fuzzy matched). Use instead of entity_id when you know the name but not the ID.
          example: Tim Cook
        - name: company_id
          in: query
          schema:
            type: integer
          description: Filter by specific company ID
        - name: company_name
          in: query
          schema:
            type: string
          description: Filter by company name or ticker (fuzzy matched). Use instead of company_id.
          example: Apple
        - name: keyword
          in: query
          schema:
            type: string
          description: Search within transcript content. Requires entity_id/entity_name or company_id/company_name.
        - name: filter_before_dt
          in: query
          schema:
            type: string
            format: date-time
          description: Only return items published before this date (ISO 8601)
        - name: filter_after_dt
          in: query
          schema:
            type: string
            format: date-time
          description: Only return items published after this date (ISO 8601)
        - name: before_feed_item_id
          in: query
          schema:
            type: integer
          description: For keyset pagination — get items older than this ID. Use last_seen_id from previous response.
        - name: page_num
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
          description: Page number for pagination
        - name: page_size
          in: query
          schema:
            type: integer
            default: 10
            minimum: 1
            maximum: 500
          description: Results per page (max 500)
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/FeedItem'
                  page_has_previous:
                    type: boolean
                  page_has_next:
                    type: boolean
                  page_num:
                    type: integer
                  last_seen_id:
                    type: integer
                    description: Use as before_feed_item_id in next request for keyset pagination
        '400':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Monthly API quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/get_companies/:
    get:
      operationId: getCompanies
      summary: Search companies
      description: |
        Search and filter companies tracked in the CEOInterviews database.
        Supports keyword search by name or ticker, and filtering by index
        membership, geography, and company type.
      parameters:
        - name: keyword
          in: query
          schema:
            type: string
          description: Search by company name or stock ticker
        - name: is_snp500
          in: query
          schema:
            type: boolean
          description: Filter for S&P 500 companies
        - name: is_nasdaq
          in: query
          schema:
            type: boolean
          description: Filter for NASDAQ-listed companies
        - name: is_snp1500
          in: query
          schema:
            type: boolean
          description: Filter for S&P 1500 companies
        - name: is_nasdaq100
          in: query
          schema:
            type: boolean
          description: Filter for NASDAQ 100 companies
        - name: is_ai_startup
          in: query
          schema:
            type: boolean
          description: Filter for AI startup companies
        - name: is_top_startup
          in: query
          schema:
            type: boolean
          description: Filter for top startup companies
        - name: is_usa_based
          in: query
          schema:
            type: boolean
          description: Filter for US-based companies
        - name: is_china_based
          in: query
          schema:
            type: boolean
          description: Filter for China-based companies
        - name: is_europe_based
          in: query
          schema:
            type: boolean
          description: Filter for Europe-based companies
        - name: is_public_company
          in: query
          schema:
            type: boolean
          description: Filter for public companies only
        - name: page_num
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
          description: Page number for pagination
        - name: page_size
          in: query
          schema:
            type: integer
            default: 10
            minimum: 1
            maximum: 500
          description: Results per page (max 500)
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/Company'
                  page_has_previous:
                    type: boolean
                  page_has_next:
                    type: boolean
                  page_num:
                    type: integer
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Monthly API quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /api/get_quotes/:
    get:
      operationId: getQuotes
      summary: Search notable executive quotes
      description: |
        Retrieve notable quotes extracted from executive media appearances.
        Filter by executive, company, content type (notable, controversial,
        financial policy), keyword, and date range. Each quote includes the
        full context of who said it, when, and where.
      parameters:
        - name: entity_id
          in: query
          schema:
            type: integer
          description: Filter by specific entity ID
        - name: entity_name
          in: query
          schema:
            type: string
          description: Filter by entity name (fuzzy matched)
        - name: company_id
          in: query
          schema:
            type: integer
          description: Filter by specific company ID
        - name: company_name
          in: query
          schema:
            type: string
          description: Filter by company name or ticker (fuzzy matched)
        - name: feed_item_id
          in: query
          schema:
            type: integer
          description: Filter by specific media appearance (feed item ID)
        - name: keyword
          in: query
          schema:
            type: string
          description: Search within quote text
        - name: is_notable
          in: query
          schema:
            type: boolean
          description: Filter for notable/important quotes only
        - name: is_controversial
          in: query
          schema:
            type: boolean
          description: Filter for controversial quotes
        - name: is_financial_policy
          in: query
          schema:
            type: boolean
          description: Filter for financial/policy-related quotes
        - name: filter_before_dt
          in: query
          schema:
            type: string
            format: date-time
          description: Only return quotes from appearances before this date (ISO 8601)
        - name: filter_after_dt
          in: query
          schema:
            type: string
            format: date-time
          description: Only return quotes from appearances after this date (ISO 8601)
        - name: before_quote_id
          in: query
          schema:
            type: integer
          description: For keyset pagination — get quotes older than this ID. Use last_seen_id from previous response.
        - name: page_num
          in: query
          schema:
            type: integer
            default: 1
            minimum: 1
          description: Page number for pagination
        - name: page_size
          in: query
          schema:
            type: integer
            default: 10
            minimum: 1
            maximum: 500
          description: Results per page (max 500)
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/Quote'
                  page_has_previous:
                    type: boolean
                  page_has_next:
                    type: boolean
                  page_num:
                    type: integer
                  num_results:
                    type: integer
                  last_seen_id:
                    type: integer
                    description: Use as before_quote_id in next request for keyset pagination
        '400':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Monthly API quota exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
