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 open, legitimate sources (see Sources).
How a request is answered#
- You name a company by its Cormorant id (
cmp_…) or an identifier (ch_uid:CHE-101.329.561,lei:…,us_cik:320193,uk_crn:…,isin:CH0038863350). - 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_ageis re-fetched first. - A company that is not yet in the register is fetched from the sources that know the identifier's scheme and added.
- The answer says per source what happened (
refresh):refreshed,fresh,failed(the register still answers),not_found,pending(slower than 2 s, or the source's canaries fail: it finishes in the background and the next request has the data) orskipped(the source is backing off after failures). Stale sources are refreshed at the same time, and the answer never waits more than about 2 s for them: you get the stored record with itsfreshnessat once.
An ISIN names the company that issued the security: Cormorant asks
GLEIF's ISIN-to-LEI mapping, fetches the issuer by its LEI and keeps the ISIN
on the record, so the next request by that ISIN is answered by the register.
An identifier no source knows is remembered as unknown for a while (ISINs
24 hours, other schemes 1 hour; refresh=true asks again), so repeating it
in bulk runs costs nothing at the sources.
Every call is metered as one company request (see
Costs & billing); answers from the register without any
refresh count as cached.
Examples#
Find a company, then read its record:
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"
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):
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. A match is put into the register right
away, so it comes back with its cmp_ id and in_register: true: read the
record with GET /v1/companies/{match.id}, no second lookup by ref needed.
Pass "persist": false to leave the register untouched (the match may then
be a live hit with id: null and a scheme:value ref).
How fast. A company already in the register is answered from it:
resolve with a confident register match and search with a near-exact
register hit do not ask any source (milliseconds). Otherwise the live
sources are asked at the same time and waited for at most 2.5 s; a source
that is slower, backing off after failures, or failing its canaries does
not hold the answer up. live_sources says per source what happened
(ok, failed, timeout, skipped) and how long it took, so you can
tell a partial answer from a complete one. After resolve stored a new
company, the other sources' data about it is fetched in the background.
Need fresher data than the freshness class? Pass max_age (seconds) or
refresh=true:
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:
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):
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
Bulk: thousands of companies#
For a list of 10,000 companies, use batch jobs, not 10,000 synchronous calls:
- Resolve once, with what you know best.
POST /v1/companies/batchwithaction: "resolve"(or/batch/csvwithname,country,city,isin,identifierscolumns). An identifier (isin,lei,ch_uid, …) is matched exactly and costs at most one source call; a name is scored over the register and the sources of itscountry(always givecountry). Items wait up to 12 s for slow sources (completeness before speed) and confident matches are stored, so every result hascompany_id. - Keep the
cmp_ids. Later runs useaction: "get"withref= thecmp_id: answered from the register, refreshed only when a source's data is older than its freshness class (or yourmax_age). - Follow changes with
GET /v1/companies/changesor a watch instead of re-reading every record.
The sources' own limits set the pace of the first run for companies not yet in the register (GLEIF: 60 requests per minute; the Swiss UID register about 20), so a first run of 10,000 new companies takes hours; repeated runs are answered from the register. Identifiers no source knows are remembered as unknown for a while and answered at once when repeated.
Read more#
- The company/v1 record: every field, claims and provenance, identifier schemes, legal forms, activity codes.
- Sources: which sources, which countries, how fresh, precedence when they disagree, licences, health.
- Change feeds and watches: follow changes without polling records.
- The full contract: Company data in the API reference.