---
title: "Search companies"
method: GET
path: "/companies"
---

# Search companies

`GET /companies`

## Request

- Base URL: `https://indexed.vc/api/v1`
- URL: `https://indexed.vc/api/v1/companies`
- Auth: API key in header `X-API-Key`
- TypeScript: <https://skmtc.dev/indexed/apis/indexed-vc-api/docs/companies/get.ts> (a function with typed inputs; its response is checked against the schema)

Search and filter companies. Every result is the full public card; `_revealed` marks entities whose depth (funding history, valuations, stacks) you have unlocked.
Standard search is free within the daily quota; paid plans spend 1 credit
per nonempty page afterward, while Free stops with SEARCH_QUOTA_EXCEEDED.
Premium search (techStack/appStack filters)
costs 3 credits on the first nonempty page; subsequent pages with a valid
`X-Search-Session` token are free for 15 minutes. Empty `data` pages consume
no delivered-search quota or credits even when `meta.total` is positive;
an unpaid empty premium page does not issue a session token. Request-rate
limits still apply.

## Query parameters

- `q` string
- `industries` string
- `countries` string
- `cities` string
- `states` string
- `employees` string
- `operatingStatus` string
- `minFunding` integer
- `maxFunding` integer
- `fundedAfter` string, date
- `fundedBefore` string, date
- `domain` string
- `minCompleteness` integer
- `updated_since` string, date-time
- `techStack` string
- `appStack` string
- `stackMatch` 'any' | 'all'
- `sort` 'total_funding_raised' | 'name' | 'last_funding_date' | 'last_funding_amount' | 'founded_year' | 'data_completeness_score'
- `order` 'asc' | 'desc'
- `page` integer
- `limit` integer
- `cursor` string
- `reveal_status` 'all' | 'revealed' | 'unrevealed'

## Headers

- `X-Search-Session` string

## Response `200`

Search results (full public cards with reveal flags)

- object
  - `data` CompanyCard[], required
    - `id` string, uuid, required
    - `name` string, required
    - `slug` string, required
    - `logo_url` string, nullable
    - `website` string, nullable
    - `short_description` string, nullable
    - `industries` string[], nullable
    - `hq_city` string, nullable
    - `hq_country` string, nullable
    - `employee_count_range` '1-10' | '11-50' | '51-200' | '201-500' | '501-1000' | '1001-5000' | '5001-10000' | '10001+' | 'null', nullable
    - `total_funding_raised` integer, nullable: Whole USD. Sum of disclosed itemized funding rounds at confidence 50+: equity rounds, notes, SAFEs, equity crowdfunding and grants. Grants are included; debt, IPOs, acquisitions and secondaries are not. Null when no counted round has a disclosed amount.
    - `operating_status` 'active' | 'acquired' | 'ipo' | 'closed' | 'null', nullable
    - `_revealed` boolean, required: true when this account has unlocked the entity's depth within 12 months
    - `domain_match` DomainMatch
      - `queried` string, required: Canonicalized domain supplied by the caller
      - `canonical_domain` string, nullable, required: Current website host on the matched company
      - `matched_via` 'canonical_domain' | 'alias_domain' | 'former_website', required
  - `meta` SearchPageMeta, required
    - `total` integer, required: Matching total before reveal_status filtering; approximate when total_is_estimate is true. Use hasMore or next_cursor for pagination.
    - `total_is_estimate` boolean: True for a planner estimate or an observed lower bound when the count timed out. Rows and pagination remain verified independently.
    - `page` integer, required
    - `limit` integer, required
    - `hasMore` boolean, required
    - `revealed_count` integer, required
    - `unrevealed_count` integer, required
    - `all_revealed` boolean: Present only when reveal_status=unrevealed and the first noncursor page verifies the complete nonempty match set is already revealed. Empty partial, cursor or later pages do not establish this; absence does not imply unrevealed matches exist.
    - `next_cursor` string, nullable: Opaque continuation token for a paid key; null means the final page. Pass it as the cursor query parameter.
    - `search_quota` object, required
      - `per_day` integer, required
      - `used_today` integer, required
      - `remaining_today` integer, required
      - `resets_at` string, date-time, required
      - `note` string: Present when this page used paid credits beyond the daily quota
    - `depth` object: Only present while this page contains unrevealed results; points to the full-record endpoint
      - `endpoint` string, required
      - `cost_credits` integer, required
      - `unlocks` string[], required
      - `docs` string, uri, required
      - `free_plan` object: Present when the key's plan does not have full API access
        - `credits_per_month` integer, required
        - `full_records_per_month` integer, required
    - `alternate_entities` object[]: Identity-only investor pointers when an exact company-domain lookup belongs to an investor; no private data
      - `entity_type` 'investor', required
      - `id` string, uuid, required
      - `name` string, required
      - `slug` string, required
      - `website` string, uri, required
      - `investor_type` string, nullable, required
      - `profile_path` string, required
    - `alternate_entities_truncated` boolean
    - `investor_lookup` string: Relative investor-domain API lookup for an exact company-domain miss with a visible investor owner
    - `resolved_filters` object: Echo of resolved filter values (e.g., industries: ai-ml → AI/ML). Only present when filters are applied.
  - `coverage_requested` boolean: Present on a zero-result exact-domain lookup: true when durably queued for coverage, false when persistence failed and the client should retry later, or when the domain belongs to a company outside coverage scope. The lookup remains free.
  - `coverage_status` 'queued' | 'not_queued' | 'pending_enrichment' | 'scope_review' | 'not_in_coverage_scope' | 'not_found': Present on a zero-result exact-domain lookup, and on a zero-result name search (q without filters). For a name search it is pending_enrichment, scope_review or not_in_coverage_scope when we hold a company with exactly that name, otherwise not_found (name misses are reviewed as search demand; nothing is promised). For a domain lookup: queued: recorded for coverage review. not_queued: recording failed; retry later. pending_enrichment: we hold this company but its profile is not yet complete enough to serve. scope_review: we hold it and its fit with coverage scope is under review. not_in_coverage_scope: we hold it but it is outside coverage scope (for example a consultancy), so it will not be served and coverage_requested is false.

## Other responses

- `400`: Invalid request parameters
- `401`: Missing, invalid, or insufficient API key
- `402`: Credits exhausted, no active credit period, or overage cap reached (code CREDIT_LIMIT_REACHED). This is a billing state, not a rate limit — do not retry. Follow top_up_url to repurchase the returned top_up_pack.
- `429`: Rate limit exceeded (code RATE_LIMITED). Back off and retry after Retry-After.

---

[API](https://skmtc.dev/indexed/apis/indexed-vc-api.md) - [All operations](https://skmtc.dev/indexed/apis/indexed-vc-api/llms.txt) - [OpenAPI document](https://skmtc.dev/indexed/apis/indexed-vc-api/revisions/c111a32d9c0c?raw)
