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

# Company Discovery (Beta)

> Company Discovery API endpoint: find companies using natural language queries across 71M+ company profiles.

## How It Works

Describe what companies you're looking for in plain English. The API translates your description into a SQL query and returns matching companies.

The generated SQL query is returned in the `generated_query` field of the response body so you can see exactly how your description was interpreted.

## Example Queries

```text theme={null}
AI startups in San Francisco with over 50 employees
public companies in the healthcare industry
fast-growing tech companies hiring aggressively
enterprise SaaS companies founded after 2015
companies with high employee turnover in the last year
```

<Note>
  For precise control over filtering, use [Company Search](/docs/api-reference/company-search) with SQL syntax instead.
</Note>

## Pagination

To page through results beyond the first 100, set `offset` to the number of rows to skip. Maximum `offset` is 10,000. Ordering is deterministic within a build, so paged requests don't overlap or skip rows; builds run on a periodic cadence, so paginate within a single client session, not across days.

```json theme={null}
{
  "query": "AI startups in San Francisco with over 50 employees",
  "limit": 100,
  "offset": 100
}
```


## OpenAPI

````yaml POST /company/discover
openapi: 3.1.0
info:
  title: Data Legion API
  description: API for enriching, searching, and discovering person and company data
  version: 1.0.0
servers:
  - url: https://api.datalegion.ai
security:
  - APIKeyHeader: []
paths:
  /company/discover:
    post:
      tags:
        - company
        - discover
      summary: Discover companies using natural language
      description: >-
        Describe the companies you're looking for in plain English. AI
        translates your description into precise database queries. The generated
        SQL is returned in the response body as `generated_query`.
      operationId: discover_companies_company_discover_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompanyDiscoverRequest'
      responses:
        '200':
          description: Success - companies found matching natural language query.
          headers:
            Total-Count-Status:
              $ref: '#/components/headers/TotalCountStatus'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyDiscoverResponse'
              example:
                matches:
                  - company:
                      legion_id: e9f2a4b6-8c3d-4e7f-a1b2-5d6e8f9a0c3b
                      name:
                        cleaned: openai inc
                        display: OpenAI
                        raw:
                          - OpenAI, Inc.
                      domain: openai.com
                      industry: technology, information and internet
                      type: private
                      size: 1001-5000
                      founded: 2015
                      linkedin_url: https://www.linkedin.com/company/openai
                      linkedin_id: '17876832'
                      legion_employee_count: 3200
                      legion_average_tenure: 18.6
                      legion_employee_growth_rate:
                        1m: 0.028
                        3m: 0.085
                        6m: 0.18
                        12m: 0.42
                      last_seen: 2026-01
                      num_sources: 4
                total: 562
                generated_query: >-
                  SELECT * FROM companies WHERE industry ILIKE '%ai%' AND type =
                  'private' AND founded >= 2010
        '400':
          description: Bad request - invalid or unclear query
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized - invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '402':
          description: Payment required - insufficient credits or expired contract
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden - API key not authorized for this endpoint
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '408':
          description: Request timeout - the query exceeded the execution time limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Payload too large - request body exceeds size limit
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error - invalid field format or value
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many requests - rate limit exceeded (50 requests per minute)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '501':
          description: Natural language search is not configured on this server
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Query generation service temporarily unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    CompanyDiscoverRequest:
      properties:
        query:
          type: string
          minLength: 3
          maxLength: 1000
          title: Query
          description: Natural language description of companies you're looking for
        limit:
          type: integer
          minimum: 1
          maximum: 100
          title: Limit
        offset:
          type: integer
          maximum: 10000
          minimum: 0
          title: Offset
          description: >-
            Number of results to skip for pagination (0-10000). Stable within a
            build; ordering may change across builds.
          default: 0
        titlecase:
          type: boolean
          title: Titlecase
          description: >-
            If true, format text fields in title case (names, company names,
            locations). Raw fields, IDs, URLs, codes, and confidence fields are
            excluded.
          default: false
        include_fields:
          anyOf:
            - type: string
            - type: 'null'
          title: Include Fields
          description: >-
            Comma-separated list of fields to include in response. If omitted,
            all fields are returned.
        exclude_fields:
          anyOf:
            - type: string
            - type: 'null'
          title: Exclude Fields
          description: >-
            Comma-separated list of fields to exclude from response. Applied
            after include_fields filter.
        pretty_print:
          type: boolean
          title: Pretty Print
          description: If true, pretty-print JSON response with indentation.
          default: false
      type: object
      required:
        - query
        - limit
      title: CompanyDiscoverRequest
      description: Request model for natural language company discovery.
      example:
        query: AI companies with 100+ employees founded after 2015
        limit: 10
    CompanyDiscoverResponse:
      allOf:
        - $ref: '#/components/schemas/CompanyMatchesResponse'
        - type: object
          required:
            - generated_query
          properties:
            generated_query:
              type: string
              title: Generated Query
              description: SQL query generated from the natural language input
      title: CompanyDiscoverResponse
      description: Company discover response with generated query.
    ErrorResponse:
      properties:
        error:
          type: string
          title: Error
          description: Error type/code
        message:
          type: string
          title: Message
          description: Human-readable error message
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - items: {}
              type: array
            - type: 'null'
          title: Details
          description: Additional error details (for validation errors)
      type: object
      required:
        - error
        - message
      title: ErrorResponse
      description: Error response model for customer-facing API.
    CompanyMatchesResponse:
      properties:
        matches:
          items:
            $ref: '#/components/schemas/CompanyMatchResponse'
          type: array
          title: Matches
          description: >-
            List of matches sorted by confidence (descending). Capped at the
            request's `limit`.
        total:
          type: integer
          title: Total
          description: >-
            For /company/search and /company/discover, the total number of rows
            matching the query's WHERE clause across the database (not just this
            page). For /company/enrich, the number of matches found for the
            input identifier. On search/discover, if the exact count exceeds its
            time budget (broad, low-selectivity queries) it falls back to the
            query planner's row estimate, and if that is unavailable, to the
            size of the returned page; the response header `Total-Count-Status`
            reports which (`exact`, `estimate`, or `page`).
      type: object
      required:
        - matches
        - total
      title: CompanyMatchesResponse
    CompanyMatchResponse:
      properties:
        company:
          $ref: '#/components/schemas/CompanyResponse'
        match_metadata:
          anyOf:
            - $ref: '#/components/schemas/MatchMetadata'
            - type: 'null'
      type: object
      required:
        - company
      title: CompanyMatchResponse
    CompanyResponse:
      properties:
        legion_id:
          type: string
          title: Legion Id
        name:
          anyOf:
            - $ref: '#/components/schemas/CompanyNameResponse'
            - type: 'null'
        headline:
          anyOf:
            - $ref: '#/components/schemas/CleanedRawResponse'
            - type: 'null'
        description:
          anyOf:
            - $ref: '#/components/schemas/CleanedRawResponse'
            - type: 'null'
        domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Domain
        linkedin_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Linkedin Url
        linkedin_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Linkedin Id
        linkedin_followers:
          anyOf:
            - type: integer
            - type: 'null'
          title: Linkedin Followers
        linkedin_employee_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Linkedin Employee Count
        industry:
          anyOf:
            - type: string
            - type: 'null'
          title: Industry
        type:
          anyOf:
            - type: string
            - type: 'null'
          title: Type
        size:
          anyOf:
            - type: string
            - type: 'null'
          title: Size
        founded:
          anyOf:
            - type: integer
            - type: 'null'
          title: Founded
        legion_employee_count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Legion Employee Count
        legion_average_tenure:
          anyOf:
            - type: number
            - type: 'null'
          title: Legion Average Tenure
        legion_new_hire_count:
          anyOf:
            - $ref: '#/components/schemas/TimeBucketIntResponse'
            - type: 'null'
        legion_attrition_count:
          anyOf:
            - $ref: '#/components/schemas/TimeBucketIntResponse'
            - type: 'null'
        legion_turnover_rate:
          anyOf:
            - $ref: '#/components/schemas/TimeBucketFloatResponse'
            - type: 'null'
        legion_employee_growth_rate:
          anyOf:
            - $ref: '#/components/schemas/TimeBucketFloatResponse'
            - type: 'null'
        legion_seniority_distribution:
          anyOf:
            - type: object
              additionalProperties:
                type: integer
            - type: 'null'
          title: Seniority Distribution
          description: >-
            Employee count by seniority level (c_level, owner, partner, vp,
            director, manager, senior, junior, training, intern)
        legion_job_function_distribution:
          anyOf:
            - type: object
              additionalProperties:
                type: integer
            - type: 'null'
          title: Job Function Distribution
          description: Employee count by job function (engineering, sales, marketing, etc.)
        legion_expense_category_distribution:
          anyOf:
            - type: object
              additionalProperties:
                type: integer
            - type: 'null'
          title: Expense Category Distribution
          description: >-
            Employee count by P&L expense category (general_and_administrative,
            research_and_development, sales_and_marketing, cost_of_services,
            not_applicable)
        legion_tenure_distribution:
          anyOf:
            - type: object
              additionalProperties:
                type: integer
            - type: 'null'
          title: Tenure Distribution
          description: Employee count by tenure bucket (<1yr, 1-2yr, 2-5yr, 5-10yr, 10+yr)
        legion_education_distribution:
          anyOf:
            - type: object
              additionalProperties:
                type: integer
            - type: 'null'
          title: Education Distribution
          description: >-
            Employee count by education level (doctorate, masters, bachelors,
            associates, high_school)
        legion_seniority_growth_rate:
          anyOf:
            - type: object
              additionalProperties:
                $ref: '#/components/schemas/TimeBucketFloatResponse'
            - type: 'null'
          title: Seniority Growth Rate
          description: Growth rate per seniority level with time buckets (1m, 3m, 6m, 12m)
        legion_job_function_growth_rate:
          anyOf:
            - type: object
              additionalProperties:
                $ref: '#/components/schemas/TimeBucketFloatResponse'
            - type: 'null'
          title: Job Function Growth Rate
          description: Growth rate per job function with time buckets (1m, 3m, 6m, 12m)
        legion_expense_category_growth_rate:
          anyOf:
            - type: object
              additionalProperties:
                $ref: '#/components/schemas/TimeBucketFloatResponse'
            - type: 'null'
          title: Expense Category Growth Rate
          description: Growth rate per expense category with time buckets (1m, 3m, 6m, 12m)
        tickers:
          items:
            $ref: '#/components/schemas/CompanyTickerResponse'
          type: array
          title: Tickers
          default: []
        socials:
          items:
            $ref: '#/components/schemas/CompanySocialResponse'
          type: array
          title: Socials
          default: []
        domains:
          items:
            $ref: '#/components/schemas/CompanyDomainResponse'
          type: array
          title: Domains
          default: []
        legion_employee_count_by_month:
          items:
            $ref: '#/components/schemas/EmployeeCountByMonthResponse'
          type: array
          title: Legion Employee Count By Month
          default: []
        num_sources:
          anyOf:
            - type: integer
            - type: 'null'
          title: Num Sources
        last_seen:
          anyOf:
            - type: string
              description: YYYY-MM format
            - type: 'null'
          title: Last Seen
        build_version:
          anyOf:
            - type: string
            - type: 'null'
          title: Build Version
      type: object
      required:
        - legion_id
      title: CompanyResponse
      description: Complete company enrichment response.
    MatchMetadata:
      properties:
        matched_on:
          items:
            type: string
          type: array
          title: Matched On
          description: Fields that matched between request and person
        match_type:
          type: string
          title: Match Type
          description: 'Type of match: exact, fuzzy, or partial'
        match_confidence:
          type: string
          title: Match Confidence
          description: 'Match confidence level: high, moderate, or low'
      type: object
      required:
        - match_type
        - match_confidence
      title: MatchMetadata
      description: Metadata about the match.
    CompanyNameResponse:
      properties:
        cleaned:
          anyOf:
            - type: string
            - type: 'null'
          title: Cleaned
        display:
          anyOf:
            - type: string
            - type: 'null'
          title: Display
          description: Best-quality name with original casing preserved (premium tier)
        raw:
          items:
            type: string
          type: array
          title: Raw
          default: []
      type: object
      title: CompanyNameResponse
      description: Company name structure with cleaned, display, and raw[] variants.
    CleanedRawResponse:
      properties:
        cleaned:
          anyOf:
            - type: string
            - type: 'null'
          title: Cleaned
        raw:
          items:
            type: string
          type: array
          title: Raw
          default: []
      type: object
      title: CleanedRawResponse
      description: >-
        Generic {cleaned, raw[]} structure used for titles, degrees, headlines,
        summaries, skills, languages, and certification names/institutions.
    TimeBucketIntResponse:
      properties:
        1m:
          anyOf:
            - type: integer
            - type: 'null'
          title: 1m
          description: Value over the last month
        3m:
          anyOf:
            - type: integer
            - type: 'null'
          title: 3m
          description: Value over the last 3 months
        6m:
          anyOf:
            - type: integer
            - type: 'null'
          title: 6m
          description: Value over the last 6 months
        12m:
          anyOf:
            - type: integer
            - type: 'null'
          title: 12m
          description: Value over the last 12 months
      type: object
      title: TimeBucketIntResponse
      description: Time-bucketed integer values (1m, 3m, 6m, 12m).
    TimeBucketFloatResponse:
      properties:
        1m:
          anyOf:
            - type: number
            - type: 'null'
          title: 1m
          description: Rate over the last month
        3m:
          anyOf:
            - type: number
            - type: 'null'
          title: 3m
          description: Rate over the last 3 months
        6m:
          anyOf:
            - type: number
            - type: 'null'
          title: 6m
          description: Rate over the last 6 months
        12m:
          anyOf:
            - type: number
            - type: 'null'
          title: 12m
          description: Rate over the last 12 months
      type: object
      title: TimeBucketFloatResponse
      description: Time-bucketed float values (1m, 3m, 6m, 12m).
    CompanyTickerResponse:
      properties:
        symbol:
          anyOf:
            - type: string
            - type: 'null'
          title: Symbol
        exchange:
          anyOf:
            - type: string
            - type: 'null'
          title: Exchange
      type: object
      title: CompanyTickerResponse
    CompanySocialResponse:
      properties:
        network:
          anyOf:
            - type: string
            - type: 'null'
          title: Network
          description: Social network name (e.g., x, github, facebook)
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
          description: Profile URL
        username:
          anyOf:
            - type: string
            - type: 'null'
          title: Username
          description: Username or handle
        id:
          anyOf:
            - type: string
            - type: 'null'
          title: Id
          description: Account ID
      type: object
      title: CompanySocialResponse
      description: Company social media profile.
    CompanyDomainResponse:
      properties:
        domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Domain
          description: Associated company domain
      type: object
      title: CompanyDomainResponse
      description: Company alternative domain.
    EmployeeCountByMonthResponse:
      properties:
        month:
          anyOf:
            - type: string
            - type: 'null'
          title: Month
          description: YYYY-MM format
        count:
          anyOf:
            - type: integer
            - type: 'null'
          title: Count
        net_change:
          anyOf:
            - type: integer
            - type: 'null'
          title: Net Change
        growth_rate:
          anyOf:
            - type: number
            - type: 'null'
          title: Growth Rate
        hires:
          anyOf:
            - type: integer
            - type: 'null'
          title: Hires
        departures:
          anyOf:
            - type: integer
            - type: 'null'
          title: Departures
      type: object
      title: EmployeeCountByMonthResponse
  headers:
    TotalCountStatus:
      description: >-
        `exact` when the response `total` is the full row count matching the
        WHERE clause across the database. `estimate` when the exact count
        exceeded its time budget (broad, low-selectivity queries) and `total` is
        the query planner's row estimate (a rough magnitude, not a precise
        figure). `page` when neither was available and `total` is just the size
        of the returned page.
      schema:
        type: string
        enum:
          - exact
          - estimate
          - page
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: API-Key

````