# SavvyIQ v3 API

> Version 2026-08-05. Base URL: https://api.savvyiq.ai

The SavvyIQ API resolves business identity. Give it a name or a domain; get back a stable
entity ID anchored to a government registration, plus the record we hold for that company.

**Preview.** The `/v3` surface is in preview. Endpoints and fields may change before general
availability.

### How the endpoints fit together

Two entry points resolve an identity; one endpoint returns the record.

| You have | Call | You get |
| --- | --- | --- |
| A company name | `GET /v3/entity-resolution/async`, then `GET /v3/jobs/{job_id}` | A `siq_` entity ID |
| A domain | `GET /v3/domain-intelligence` | A `siq_` entity ID, plus what the domain is |
| A `siq_` entity ID | `GET /v3/entities/{id}` | The full record |

Resolve once, store the `siq_` ID, and read the record from `/v3/entities/{id}` from then on.
IDs are stable.

### One entity shape

Every endpoint serves the same identity core: `legal_name` and `display_name`, `status`,
`description`, `website`, `headquarters`, typed `identifiers[]`, and `primary_legal_entity`,
the government registration that anchors the record.

The endpoints differ only in how much they add on top. Entity resolution adds `facets`
(ownership and legal form) and scheme-keyed industry codes under `industry.schemes`.
`/v3/entities/{id}` adds those plus the enrichment: firmographics, classification labels,
operational footprint, social profiles. `/v3/domain-intelligence` serves the identity core
alone, next to everything it knows about the domain itself.

## Endpoints

### Entity Resolution

- `GET /v3/entity-resolution/async` — Resolve a company name → /docs/v3/reference/entity-resolution/get-v3-entity-resolution-async.md
- `GET /v3/jobs/{job_id}` — Poll a resolution job → /docs/v3/reference/entity-resolution/get-v3-jobs-job-id.md

### Entity Record

- `GET /v3/entities/{id}` — Get an entity record → /docs/v3/reference/entity-record/get-v3-entities-id.md

### Domain Intelligence

- `GET /v3/domain-intelligence` — Resolve a domain → /docs/v3/reference/domain-intelligence/get-v3-domain-intelligence.md

## Quickstart

Every request needs an `apikey` header. The base URL is `https://api.savvyiq.ai`.

## 1. Resolve a name

Resolution runs real research, so it is asynchronous. The kickoff returns immediately.

```bash
curl -G 'https://api.savvyiq.ai/v3/entity-resolution/async' \
  --data-urlencode 'name=Datadog' \
  --data-urlencode 'location=New York, NY' \
  --data-urlencode 'include=basis' \
  -H 'apikey: YOUR_API_KEY'
```

```json
{
  "status": "pending",
  "job_id": "019fe975-186e-707c-b59a-b0a6c9914221",
  "request_id": "reqa_344tSxhAVACWbuENINJ9D"
}
```

## 2. Poll for the result

Poll with either the `job_id` or the `request_id`. Both identify the same job. `202` means
still running, `200` means finished. Repeat `include=basis` here — the kickoff records the
provenance, the poll asks for it in the body.

```bash
curl -G 'https://api.savvyiq.ai/v3/jobs/019fe975-186e-707c-b59a-b0a6c9914221' \
  --data-urlencode 'include=basis' \
  -H 'apikey: YOUR_API_KEY'
```

## 3. Read the record

Take `entity.id` from the result and fetch the full record. Store that ID. It is stable.

```bash
curl 'https://api.savvyiq.ai/v3/entities/siq_33d67jj0wJESjEdFHMhuQ' \
  -H 'apikey: YOUR_API_KEY'
```

## Starting from a domain

Domain lookups are synchronous: one call returns the operating entity and what we know about
the domain itself.

```bash
curl 'https://api.savvyiq.ai/v3/domain-intelligence?domain=datadoghq.com' \
  -H 'apikey: YOUR_API_KEY'
```

`domain` accepts a bare domain, a full URL, or an email address. All are normalized to the
root domain.

## Concepts

## Entities and candidates

An **entity** is a confirmed record, anchored to a government registration. A **candidate**
is our best hypothesis when we could not confirm one, either because confidence was too low
to separate two matches or because the entity type is not fully supported yet. Today
confirmed records are incorporated businesses. Sole proprietors, partnerships, governments
and funds come back as candidates. A response populates `entity` or `candidate`, never both.
`type` and `subtype` tell you what was found either way.

## Identifiers

Three ID levels, one system.

| Prefix | Level | Use |
| --- | --- | --- |
| `siq_` | Global entity | Your primary key, and the only ID `/v3/entities/{id}` accepts |
| `op_` | Operational presence | How the entity operates in one country |
| `le_` | Legal entity | One specific registration in one jurisdiction |

A global entity can have many registrations: a Delaware corporation, a UK subsidiary, and so
on. `primary_legal_entity` is the anchoring one. `le_` and `op_` IDs appear inside records
but are not lookup keys.

`siq_` IDs are stable. If two records are consolidated, the response returns
`status: "merged"` with `merged_into` set, and serves the canonical record. Store the new ID.

Entities also carry external identifiers in `identifiers[]`: registry registration IDs, LEI,
CIK and others where known. See [Codes & enums](/docs/v3/guides/codes-enums/).

## Registry-first data

Every confirmed entity is anchored to an official government registration. That anchor is
what keeps IDs stable and what separates two companies that share a name. On top of it,
research agents search
registries, directories, news and the company's own site, then attach what they find to the
registration.

## Confidence and provenance

`match_confidence` (0-100) says how certain we are that the result is the entity you asked
for. `factors[]` lists the strengths and limitations behind that score, and `actions[]`
suggests what to add when a query is ambiguous. Both use stable codes. See
[Codes & enums](/docs/v3/guides/codes-enums/).

Pass `include=basis` for per-field provenance: for each field, the confidence, the reasoning,
and citations back to the sources, each tagged with an authority tier.

## Freshness

Registry data updates on each registrar's cadence. Web-sourced enrichment refreshes
periodically. `/v3/entities/{id}` never blocks: it serves what exists now and reports the
build state in `enrichment.status`. When a record has never been enriched, the first read
starts the build in the background. Poll until `enrichment.status` is `complete`.

## Authentication

Authenticate with an API key sent in the `apikey` header. Find your key in the
[dashboard](https://savvyiq.ai/api-keys).

```bash
curl 'https://api.savvyiq.ai/v3/entities/siq_33d67jj0wJESjEdFHMhuQ' \
  -H 'apikey: YOUR_API_KEY'
```

A missing or invalid key returns `401`. An account not yet enabled for the v3 API returns
`403 no_pricing_configured`. Contact us and we will switch it on.

## Rate limits

Limits are per minute, per key, and differ by endpoint.

| Endpoint | Limit |
| --- | --- |
| `GET /v3/entity-resolution/async` | 600 / minute |
| `GET /v3/domain-intelligence` | 600 / minute |
| `GET /v3/jobs/{job_id}` | 100 / minute |
| `GET /v3/entities/{id}` | 100 / minute |

Exceeding a limit returns `429`. Email us if you need more.

| Header | Meaning |
| --- | --- |
| `X-RateLimit-Limit-Minute` | Requests permitted per minute |
| `X-RateLimit-Remaining-Minute` | Requests left in the current window |
| `RateLimit-Reset` | Seconds until the window resets |

## Codes & enums

Closed vocabularies used across `/v3` responses. Values may be **added** in a minor version.
Within a major version no value is removed or redefined. Tolerate values you do not
recognise.

## Resolution status

<ul class="code-grid"><li>matched</li><li>partial_match</li><li>inconclusive</li><li>no_match</li><li>not_found</li><li>pending</li><li>merged</li></ul>

## Entity status

`null` when unknown.

<ul class="code-grid"><li>active</li><li>inactive</li></ul>

## Enrichment status

On `enrichment.status`, and on the top-level `status` of a domain lookup.

<ul class="code-grid"><li>pending</li><li>building</li><li>refreshing</li><li>complete</li><li>failed</li></ul>

## Entity type

`type`

<ul class="code-grid"><li>business</li><li>nonprofit</li><li>government</li><li>person</li><li>other</li><li>unknown</li></ul>

`subtype`

<ul class="code-grid"><li>incorporated_entity</li><li>unincorporated_entity</li><li>nonprofit_entity</li><li>government_entity</li><li>natural_person</li><li>complex_business_structure</li><li>trading_name_only</li><li>other_entity</li><li>unknown</li></ul>

## Facets

`facets` describes ownership and legal form, not industry. Industry codes live under
`industry.schemes`.

`sector`

<ul class="code-grid"><li>private</li><li>public</li><li>government</li><li>nonprofit</li></ul>

`legal_form`. `corporation` is the generic incorporated form. `c_corp` and `s_corp` are used
only when a source states the election explicitly.

<ul class="code-grid"><li>llc</li><li>corporation</li><li>c_corp</li><li>s_corp</li><li>lp</li><li>llp</li><li>gp</li><li>sole_proprietorship</li><li>nonprofit_corp</li><li>pllc</li><li>pc</li><li>cooperative</li><li>municipal_agency</li><li>government_entity</li><li>trust</li><li>unknown</li></ul>

## Business model axes

On `classification`, ordered most-material-first. Index 0 is the dominant value, so group on
it rather than exploding the array. `[]` means undetermined. `market_segments` returns at
most two values and `revenue_models` at most three. `b2b2c` is never returned alongside
`b2b` or `b2c`. Both axes describe the resource that returns them: a domain describes that
domain's motion, an entity describes the whole company.

`market_segments`

<ul class="code-grid"><li>b2b</li><li>b2c</li><li>b2g</li><li>b2b2c</li></ul>

`revenue_models`

<ul class="code-grid"><li>subscription</li><li>usage_based</li><li>transaction_fee</li><li>marketplace</li><li>product_sales</li><li>services</li><li>advertising</li><li>licensing</li><li>lending_and_deposits</li><li>insurance_premium</li><li>leasing_rental</li><li>grants_donations</li></ul>

## Industry schemes

`industry.schemes` is keyed by scheme: `naics_2022` and `sic`. A scheme that was not
classified is absent, and an empty key is never returned. Within a scheme, the primary code
comes first.

## Identifier types

Returned in this order, canonicalized per type.

| Type | Format |
| --- | --- |
| `registration_id` | As issued by the registry, with the issuing `jurisdiction` |
| `cik` | Zero-padded to 10 digits |
| `lei` | 20 alphanumerics |
| `bic` | 8 or 11 characters |
| `ein` | `##-#######` |
| `duns` | 9 bare digits |
| `ticker` | Uppercase symbol |

## Basis provenance

With `include=basis`, each entry's `confidence` is `high`, `medium` or `low`, and every
citation carries a `source_type` and an `authority_tier`.

| `source_type` | `authority_tier` |
| --- | --- |
| `government_registry` | 1 |
| `public_profile` | 2 |
| `company_website` | 3 |
| `web` | 3 |

## Factor codes

`factors[]` entries have a `type` of `strength` or `limitation` and a stable `code`. Each
entry also carries its own `description` and `impact`, so you rarely need to map codes
yourself. `other` is the escape hatch on both lists.

Strengths

<ul class="code-grid"><li>name_exact_match</li><li>name_close_match</li><li>location_confirmed</li><li>jurisdiction_match</li><li>industry_match</li><li>registration_number_match</li><li>multiple_sources_corroboration</li><li>legal_entity_confirmed</li><li>headquarters_match</li><li>foreign_branch_match</li><li>branch_vs_subsidiary_clarity</li><li>legal_registration_verified</li><li>registry_identifier_anchored</li><li>legal_entity_confirmed_on_website</li><li>domain_content_matches_entity</li><li>consistent_entity_references</li><li>current_ownership_verified</li><li>website_official_status</li><li>authoritative_legal_documentation</li></ul>

Limitations

<ul class="code-grid"><li>no_location_provided</li><li>location_mismatch</li><li>multiple_potential_entities</li><li>name_too_generic</li><li>name_mismatch</li><li>numeric_identifier_only</li><li>insufficient_data</li><li>max_iterations_reached</li><li>no_legal_entity_confirmed</li><li>unsupported_entity_type</li><li>limited_entity_type_support</li><li>parent_entity_confusion</li><li>jurisdiction_mismatch</li><li>no_branch_registration_found</li><li>separate_legal_entities</li><li>product_vs_company</li><li>brand_vs_legal_entity_confusion</li><li>no_legal_entity_on_website</li><li>limited_domain_information</li><li>multiple_entities_mentioned</li><li>domain_ownership_changed</li><li>conflicting_ownership_info</li><li>domain_parked_or_inactive</li><li>entity_merged_redirect</li><li>reasoning_degraded</li></ul>

## Action codes

`actions[]` suggests how to sharpen an ambiguous query.

<ul class="code-grid"><li>add_location</li><li>clarify_name</li><li>provide_full_legal_name</li><li>specify_entity_relationship</li><li>specify_identifier_type</li><li>include_industry_context</li><li>search_for_parent_company</li><li>include_entity_name</li><li>add_jurisdiction</li></ul>

## Domain context

`domain_type`

<ul class="code-grid"><li>corporate_website</li><li>infrastructure</li><li>service_platform</li><li>email_domain</li><li>api_endpoint</li><li>cdn_domain</li><li>subdomain</li><li>parked_domain</li><li>personal_site</li><li>content_platform</li><li>placeholder_page</li><li>non_business</li><li>other</li></ul>

`domain_relationship`

<ul class="code-grid"><li>direct_owner</li><li>parent_company</li><li>infrastructure_provider</li><li>service_provider</li><li>email_provider</li><li>platform_provider</li></ul>
