Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Indexed.vc Companies API
version: 1.0.0
description: 'Company intelligence API providing comprehensive data on private companies,
funding history, and investor relationships.'
contact:
name: Indexed.vc Support
url: https://indexed.vc
license:
name: Proprietary
servers:
- url: https://indexed.vc/api/v1
description: Production
security:
- ApiKeyAuth: []
tags:
- name: Companies
paths:
/companies:
get:
operationId: searchCompanies
summary: Search companies
description: '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 page; subsequent pages with a valid
`X-Search-Session` token are free for 15 minutes.'
parameters:
- name: q
in: query
schema:
type: string
maxLength: 200
description: Free text search query
- name: industries
in: query
schema:
type: string
description: Comma-separated industry filters. Accepts display labels (Fintech), case variants (fintech), or slugs (ai-ml). Use GET /industries for valid values.
- name: countries
in: query
schema:
type: string
description: Comma-separated country names (e.g., United States,United Kingdom)
- name: employees
in: query
schema:
type: string
description: 'Comma-separated employee ranges: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+'
- name: operatingStatus
in: query
schema:
type: string
description: 'Comma-separated: active, acquired, ipo, closed, merged'
- name: minFunding
in: query
schema:
type: integer
minimum: 0
description: Minimum total funding (total_funding_raised, grants included) in whole USD
- name: maxFunding
in: query
schema:
type: integer
minimum: 0
description: Maximum total funding (total_funding_raised, grants included) in whole USD
- name: domain
in: query
schema:
type: string
description: 'Match a company by its website domain (enrichment lookup, e.g. stripe.com). EXACT registrable-domain matching: matches mercury.com and any subdomain (www./app.mercury.com) but never superstrings like bluemercury.com. Accepts bare domains or full URLs.'
- name: minCompleteness
in: query
schema:
type: integer
minimum: 0
maximum: 64
description: Minimum data_completeness_score — skip thin records
- name: updated_since
in: query
schema:
type: string
format: date-time
description: 'Incremental sync: only records modified at/after this ISO date or timestamp (updated_at watermark). Combine with cursor pagination for drift-free delta pulls.'
- name: techStack
in: query
schema:
type: string
description: 'Comma-separated technology names (triggers premium search: 3 credits)'
- name: appStack
in: query
schema:
type: string
description: 'Comma-separated app/tool names (triggers premium search: 3 credits)'
- name: stackMatch
in: query
schema:
type: string
enum:
- any
- all
default: any
description: Match mode for tech/app stack filters
- name: sort
in: query
schema:
type: string
enum:
- total_funding_raised
- name
- last_funding_date
- last_funding_amount
- founded_year
- data_completeness_score
- name: order
in: query
schema:
type: string
enum:
- asc
- desc
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 25
- name: cursor
in: query
schema:
type: string
description: Paid plans only. Keyset cursor for sequential bulk pulls. Free keys use page=1 through page=3. Pass meta.next_cursor from the prior page; ignores page/sort.
- name: reveal_status
in: query
schema:
type: string
enum:
- all
- revealed
- unrevealed
default: all
description: Filter results by reveal state
- name: X-Search-Session
in: header
schema:
type: string
description: Session token for free premium search pagination (15-min TTL)
responses:
'200':
description: Search results (full public cards with reveal flags)
headers:
X-Request-Id:
schema:
type: string
format: uuid
X-Credits-Cost:
schema:
type: integer
X-Search-Session:
schema:
type: string
description: Premium search session token
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
X-RateLimit-Reset:
schema:
type: integer
description: Unix timestamp
content:
application/json:
schema:
type: object
required:
- data
- meta
properties:
data:
type: array
items:
$ref: '#/components/schemas/CompanyCard'
meta:
$ref: '#/components/schemas/SearchPageMeta'
coverage_requested:
type: boolean
description: '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:
type: string
enum:
- queued
- not_queued
- pending_enrichment
- scope_review
- not_in_coverage_scope
- not_found
description: '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.'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/AuthError'
'402':
$ref: '#/components/responses/PaymentRequired'
'429':
$ref: '#/components/responses/RateLimited'
tags:
- Companies
/companies/lookup:
post:
operationId: lookupCompanyDomains
summary: Look up up to 100 company domains
description: 'Batch form of `GET /companies?domain=…`. Inputs are normalized and
deduplicated in first-seen order. Each delivered hit costs 1 credit;
misses are free. A miss reports whether review was durably queued,
is pending enrichment, needs scope review, or is outside our coverage;
no miss promises admission. Alias and
former-domain hits include `domain_match` so a different canonical
website is explicit rather than surprising.'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- domains
additionalProperties: false
properties:
domains:
type: array
minItems: 1
maxItems: 100
items:
type: string
maxLength: 500
responses:
'200':
description: Ordered per-domain lookup results
headers:
X-Request-Id:
schema:
type: string
format: uuid
X-Credits-Cost:
schema:
type: integer
description: Total credits charged for delivered hits
X-Credits-Remaining:
schema:
type: integer
description: Current combined included and pack balance after delivered hits
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
X-RateLimit-Reset:
schema:
type: integer
description: Unix timestamp
content:
application/json:
schema:
type: object
required:
- data
- summary
properties:
data:
type: array
items:
$ref: '#/components/schemas/CompanyDomainLookupItem'
summary:
$ref: '#/components/schemas/CompanyDomainLookupSummary'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/AuthError'
'402':
$ref: '#/components/responses/PaymentRequired'
'429':
$ref: '#/components/responses/RateLimited'
tags:
- Companies
/companies/{slug}:
get:
operationId: getCompany
summary: Get company by slug
description: 'Fetch a single company profile. Cost varies by depth:
**valuation_events field schema** (returned at `depth=full`): each
round object carries `event_type`, `round_name`, `amount_raised_usd`
(whole USD; also mirrored as `amount_raised`), `announced_date`
(YYYY-MM-DD), `pre_money_valuation` / `post_money_valuation`,
`press_url`, `confidence_score`, and `participants[]` (investors with
`is_lead`). Note: valuation-only events (409A marks, some tender
offers) legitimately have `amount_raised_usd: null` — a null amount
is "undisclosed/not applicable", not missing data. `data_as_of` on the
response is when this record was last verified by enrichment.
- `slim` (1 credit): identity fields only
- `standard` (2 credits): company scalars plus reviewed ownership links; no funding events, valuations or stack
- `full` (3 credits): complete data — funding rounds, investors, tech/app stack, valuations'
parameters:
- name: slug
in: path
required: true
schema:
type: string
pattern: ^[a-z0-9][a-z0-9-]*[a-z0-9]$
- name: depth
in: query
schema:
type: string
enum:
- slim
- standard
- full
default: standard
responses:
'200':
description: Company profile
headers:
X-Request-Id:
schema:
type: string
format: uuid
X-Credits-Cost:
schema:
type: integer
X-Credits-Cached:
schema:
type: string
enum:
- 'true'
content:
application/json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/CompanyProfile'
'400':
$ref: '#/components/responses/ValidationError'
'401':
$ref: '#/components/responses/AuthError'
'404':
$ref: '#/components/responses/NotFoundError'
'503':
description: Credit service or prior-charge cache unavailable (SYSTEM_ERROR). Cache-read failures do not charge. A lost deduction response can have an unknown billing outcome; check credit usage before retrying.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
tags:
- Companies
components:
schemas:
CompanyDomainLookupSummary:
type: object
required:
- total_requested
- total_hits
- total_misses
- total_insufficient_credits
- total_credits_charged
properties:
total_requested:
type: integer
total_hits:
type: integer
total_misses:
type: integer
total_insufficient_credits:
type: integer
total_credits_charged:
type: integer
DomainMatch:
type: object
required:
- queried
- canonical_domain
- matched_via
properties:
queried:
type: string
description: Canonicalized domain supplied by the caller
canonical_domain:
type:
- string
- 'null'
description: Current website host on the matched company
matched_via:
type: string
enum:
- canonical_domain
- alias_domain
- former_website
CompanyDomainLookupItem:
oneOf:
- type: object
required:
- domain
- status
- credits_charged
- data
properties:
domain:
type: string
status:
type: string
const: hit
credits_charged:
type: integer
const: 1
data:
$ref: '#/components/schemas/CompanyCard'
- type: object
required:
- domain
- status
- coverage_requested
- coverage_eta_days
- credits_charged
properties:
domain:
type: string
status:
type: string
const: miss
coverage_requested:
type: boolean
description: true when the request was durably recorded for manual review; not a promise of admission or coverage. false means recording failed and the client can retry, or the domain belongs to a company outside coverage scope
coverage_status:
type: string
enum:
- queued
- not_queued
- pending_enrichment
- scope_review
- not_in_coverage_scope
description: 'Why this domain missed: queued (recorded for review), not_queued (recording failed), pending_enrichment (held, profile not yet servable), scope_review (held, scope under review), not_in_coverage_scope (held, outside coverage scope; never served)'
coverage_eta_days:
type:
- integer
- 'null'
description: 'Currently null: manual review has no guaranteed completion date. Misses are never charged.'
credits_charged:
type: integer
const: 0
- type: object
required:
- domain
- status
- credits_charged
properties:
domain:
type: string
status:
type: string
const: insufficient_credits
credits_charged:
type: integer
const: 0
ApiError:
type: object
required:
- error
- code
properties:
error:
type: string
description: Human-readable error message
code:
type: string
description: Machine-readable error code
reason:
type: string
enum:
- credits_exhausted
- overage_cap_reached
- no_active_period
remaining:
type: integer
minimum: 0
top_up_url:
type: string
format: uri
top_up_pack:
type: object
properties:
id:
type: string
example: pack_5k
credits:
type: integer
example: 5000
price_cents:
type: integer
example: 20000
request_id:
type: string
format: uuid
description: Correlation ID (also in X-Request-Id header)
details:
type: array
description: Present for validation errors
items:
type: object
properties:
field:
type: string
message:
type: string
CompanyCard:
type: object
required:
- id
- name
- slug
- _revealed
properties:
id:
type: string
format: uuid
name:
type: string
slug:
type: string
logo_url:
type:
- string
- 'null'
website:
type:
- string
- 'null'
short_description:
type:
- string
- 'null'
industries:
type:
- array
- 'null'
items:
type: string
hq_city:
type:
- string
- 'null'
hq_country:
type:
- string
- 'null'
employee_count_range:
type:
- string
- 'null'
enum:
- 1-10
- 11-50
- 51-200
- 201-500
- 501-1000
- 1001-5000
- 5001-10000
- 10001+
- null
total_funding_raised:
type:
- integer
- 'null'
description: '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:
type:
- string
- 'null'
enum:
- active
- acquired
- ipo
- closed
- null
_revealed:
type: boolean
description: true when this account has unlocked the entity's depth within 12 months
domain_match:
$ref: '#/components/schemas/DomainMatch'
SearchPageMeta:
type: object
required:
- total
- page
- limit
- hasMore
- revealed_count
- unrevealed_count
- search_quota
properties:
total:
type: integer
description: Total matches (always full count, regardless of reveal_status filter)
page:
type: integer
limit:
type: integer
hasMore:
type: boolean
revealed_count:
type: integer
unrevealed_count:
type: integer
all_revealed:
type: boolean
description: Present when reveal_status=unrevealed but all matches are already revealed
next_cursor:
type:
- string
- 'null'
description: Opaque continuation token for a paid key; null means the final page. Pass it as the cursor query parameter.
search_quota:
type: object
required:
- per_day
- used_today
- remaining_today
- resets_at
properties:
per_day:
type: integer
used_today:
type: integer
remaining_today:
type: integer
resets_at:
type: string
format: date-time
note:
type: string
description: Present when this page used paid credits beyond the daily quota
depth:
type: object
description: Only present while this page contains unrevealed results; points to the full-record endpoint
required:
- endpoint
- cost_credits
- unlocks
- docs
properties:
endpoint:
type: string
cost_credits:
type: integer
unlocks:
type: array
items:
type: string
docs:
type: string
format: uri
free_plan:
type: object
description: Present when the key's plan does not have full API access
required:
- credits_per_month
- full_records_per_month
properties:
credits_per_month:
type: integer
full_records_per_month:
type: integer
alternate_entities:
type: array
description: Identity-only investor pointers when an exact company-domain lookup belongs to an investor; no private data
items:
type: object
required:
- entity_type
- id
- name
- slug
- website
- investor_type
- profile_path
properties:
entity_type:
type: string
const: investor
id:
type: string
format: uuid
name:
type: string
slug:
type: string
website:
type: string
format: uri
investor_type:
type:
- string
- 'null'
profile_path:
type: string
alternate_entities_truncated:
type: boolean
resolved_filters:
type: object
description: 'Echo of resolved filter values (e.g., industries: ai-ml → AI/ML). Only present when filters are applied.'
additionalProperties: true
CompanyRelationship:
type: object
properties:
relationship_type:
type: string
enum:
- subsidiary
- brand
- division
- joint_venture
ownership_pct:
type:
- number
- 'null'
description: Stated ownership percentage when a source gives it
started_on:
type:
- string
- 'null'
format: date
company:
type: object
properties:
id:
type: string
format: uuid
slug:
type: string
name:
type: string
logo_url:
type:
- string
- 'null'
CompanyProfile:
type: object
required:
- id
- name
- slug
description: Shape varies by depth parameter (slim/standard/full)
properties:
id:
type: string
format: uuid
name:
type: string
slug:
type: string
data_as_of:
type:
- string
- 'null'
format: date-time
description: Last verified enrichment timestamp; null when unknown.
logo_url:
type:
- string
- 'null'
website:
type:
- string
- 'null'
short_description:
type:
- string
- 'null'
long_description:
type:
- string
- 'null'
industries:
type:
- array
- 'null'
items:
type: string
hq_city:
type:
- string
- 'null'
hq_state:
type:
- string
- 'null'
hq_country:
type:
- string
- 'null'
employee_count_range:
type:
- string
- 'null'
total_funding_raised:
type:
- integer
- 'null'
description: '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:
type:
- string
- 'null'
founded_year:
type:
- integer
- 'null'
last_valuation:
type:
- integer
- 'null'
description: Null at slim/standard depth or when undisclosed.
last_valuation_date:
type:
- string
- 'null'
format: date
description: Null at slim/standard depth or when unknown.
owners:
type: array
description: 'depth=standard and full. Companies that own this one, from reviewed, sourced relationships: its controlling parent (subsidiary, brand or division), or its joint-venture owners. Empty when none is recorded.'
items:
$ref: '#/components/schemas/CompanyRelationship'
subsidiaries:
type: array
description: depth=standard and full. Companies this one owns (subsidiaries, brands, divisions, joint ventures), up to 200, by name.
items:
$ref: '#/components/schemas/CompanyRelationship'
valuation_events:
type: array
description: Only present at depth=full
items:
type: object
properties:
id:
type: string
format: uuid
event_type:
type: string
amount_raised_usd:
type:
- integer
- 'null'
announced_date:
type:
- string
- 'null'
format: date
participants:
type: array
items:
type: object
properties:
is_lead:
type: boolean
investor:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
slug:
type: string
investor_type:
type:
- string
- 'null'
technologies:
type: array
description: Only present at depth=full
items:
type: object
properties:
technology_name:
type: string
category:
type:
- string
- 'null'
stack_type:
type: string
const: tech
app_stack:
type: array
description: Only present at depth=full
items:
type: object
properties:
technology_name:
type: string
category:
type:
- string
- 'null'
stack_type:
type: string
const: app
responses:
ValidationError:
description: Invalid request parameters
headers:
X-Request-Id:
schema:
type: string
format: uuid
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
AuthError:
description: Missing, invalid, or insufficient API key
headers:
X-Request-Id:
schema:
type: string
format: uuid
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
RateLimited:
description: Rate limit exceeded (code RATE_LIMITED). Back off and retry after Retry-After.
headers:
X-Request-Id:
schema:
type: string
format: uuid
X-RateLimit-Limit:
schema:
type: integer
X-RateLimit-Remaining:
schema:
type: integer
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
NotFoundError:
description: Entity not found
headers:
X-Request-Id:
schema:
type: string
format: uuid
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
PaymentRequired:
description: '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.
'
headers:
X-Request-Id:
schema:
type: string
format: uuid
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
description: API key in format `idx_<32chars>`. Available on every plan; entity detail and reveal spend credits on every plan, while bulk enrichment, webhooks, scheduled exports and listing/sorting require a paid plan (Silver+).