# Company data

Cormorant keeps a **company register**: one structured record per company
anyone has asked about, with every value attributed to the source that
published it, when it was seen and the raw document it came from. Records
are versioned, never thrown away, refreshed when they are asked for again,
and kept current by official change feeds. Data comes from official
registers, GLEIF and other free, legitimate sources (see
[Sources](/docs/companies-sources.md)).

## How a request is answered

1. You name a company by its Cormorant id (`cmp_…`) or an identifier
   (`ch_uid:CHE-101.329.561`, `lei:…`, `us_cik:320193`, `uk_crn:…`).
2. Cormorant answers from the register. For each source that knows the
   company, data older than the source's **freshness class** (registry core
   24 h, people 7 days, …) or your `max_age` is re-fetched first.
3. A company that is not yet in the register is fetched from the sources
   that know the identifier's scheme and added.
4. The answer says per source what happened (`refresh`): `refreshed`,
   `fresh`, `failed` (the register still answers), `not_found`.

Every call is metered as one `company` request (see
[Costs & billing](/docs/billing.md)); answers from the register without any
refresh count as `cached`.

## Examples

Find a company, then read its record:

```sh
curl -s "https://api.cormorant.ch/v1/companies/search?q=UBS%20Group&country=CH" \
  -H "Authorization: Bearer $CORMORANT_API_KEY"

curl -s "https://api.cormorant.ch/v1/companies/lei:549300SZJ9VS8SGXAN81?include=ownership" \
  -H "Authorization: Bearer $CORMORANT_API_KEY"
```

```python
import os, httpx

api = httpx.Client(
    base_url="https://api.cormorant.ch",
    headers={"Authorization": f"Bearer {os.environ['CORMORANT_API_KEY']}"},
)
hits = api.get("/v1/companies/search", params={"q": "UBS Group", "country": "CH"}).json()
best = hits["results"][0]
record = api.get(f"/v1/companies/{best['ref']}", params={"include": "people,ownership"}).json()
print(record["names"]["legal"], record["status"]["value"])
for field, p in record["provenance"].items():
    print(field, "from", p["source"], "seen", p["observed_at"])
```

Match a name to a company (entity resolution):

```sh
curl -s -X POST https://api.cormorant.ch/v1/companies/resolve \
  -H "Authorization: Bearer $CORMORANT_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "UBS AG", "country": "CH", "city": "Zürich"}'
```

`match` is set only when one candidate is a confident match; otherwise read
`candidates` and their `reasons`.

Need fresher data than the freshness class? Pass `max_age` (seconds) or
`refresh=true`:

```sh
curl -s "https://api.cormorant.ch/v1/companies/ch_uid:CHE-101.329.561?max_age=3600" \
  -H "Authorization: Bearer $CORMORANT_API_KEY"
```

What changed and when — every value each source ever asserted:

```sh
curl -s "https://api.cormorant.ch/v1/companies/ch_uid:CHE-101.329.561/history?field=names.legal" \
  -H "Authorization: Bearer $CORMORANT_API_KEY"
```

Many companies at once: a batch job (JSON or CSV in, JSON or CSV out):

```sh
curl -s -X POST https://api.cormorant.ch/v1/companies/batch \
  -H "Authorization: Bearer $CORMORANT_API_KEY" -H "Content-Type: application/json" \
  -d '{"action": "get", "items": [{"ref": "lei:BFM8T61CT2L1QCEMIK50"}, {"ref": "ch_uid:CHE-116.281.710"}],
       "idempotency_key": "crm-sync-2026-10-20"}'
# then: GET /v1/jobs/{job_id}?include=items  or  GET /v1/companies/batch/{job_id}.csv
```

## Read more

- [The company/v1 record](/docs/companies-model.md): every field, claims and
  provenance, identifier schemes, legal forms, activity codes.
- [Sources](/docs/companies-sources.md): which sources, which countries, how fresh,
  precedence when they disagree, licences, health.
- [Change feeds and watches](/docs/companies-changes.md): follow changes without
  polling records.
- The full contract: [Company data in the API reference](/docs/api.md#company-data).
