companies-and-finance.md (36742B)
1 --- 2 title: "Companies, Ownership & Finance" 3 description: "Corporate registries, filings and beneficial-ownership data for working out who actually controls a company." 4 category: osint 5 subcategory: "Corporate & Financial" 6 tags: [osint, companies, finance, ownership, filings] 7 tools: [opencorporates, edgar, edgartools, aleph, companies-house, opensanctions, icij-offshore-leaks] 8 difficulty: intermediate 9 updated: 2026-10-03 10 references: 11 - name: "Bellingcat's Online Investigation Toolkit" 12 url: "https://bellingcat.gitbook.io/toolkit" 13 author: "Bellingcat" 14 license: none 15 relation: derived 16 note: "Tool catalogue: names, descriptions, cost flags and links for this area." 17 - name: "OSINT Newsletter Tools Library" 18 url: "https://tools.osintnewsletter.com" 19 author: "The OSINT Newsletter" 20 license: none 21 relation: derived 22 note: "Second tool catalogue, cross-checked against the above." 23 --- 24 25 ## What this covers 26 27 Establishing what a company is, who owns it, and what it has told regulators. The pattern that 28 matters: the registry tells you the *legal* structure, and the legal structure is often designed to 29 obscure who benefits. Getting to the human at the end takes several sources in a particular order. 30 31 ## Method 32 33 1. **Start at the national registry**, which is authoritative. Aggregators are convenient but 34 stale, and for anything you will publish the registry page is the citation. 35 2. **Get the registration number** and use it thereafter. Company names are reused across 36 jurisdictions, reused within them after dissolution, and changed deliberately. 37 3. **Pull the filings, not the summary.** Annual accounts, director appointments and charges carry 38 addresses, signatures, auditors and related parties that the summary page omits. The scanned PDF 39 often has a signature and a handwritten date the structured data does not. 40 4. **Follow officers sideways.** One director's other appointments frequently reveal the group the 41 company actually belongs to — and distinguish a decision-maker from a nominee, because a 42 nominee has dozens or hundreds. 43 5. **Screen the names you have** against sanctions and politically-exposed-person data before you 44 go further. A hit changes what the rest of the chain means, and it is cheap to check. 45 6. **Cross-border means repeating the whole process** in each jurisdiction, and each one publishes 46 something different: the UK publishes officers and PSCs free, Delaware publishes almost nothing, 47 the EU publishes through BRIS with per-country gaps, and secrecy jurisdictions publish the 48 existence of the company and nothing else. A chain terminating in one of them is the normal 49 outcome, not a failure. 50 7. **Check leak archives where the chain goes dark.** OCCRP Aleph and ICIJ Offshore Leaks hold what 51 registries do not, with the caveat that leaked data is a snapshot of one moment. 52 8. **Write down what each jurisdiction refused to tell you.** "Beneficial owner not published in 53 this jurisdiction" is a finding about the structure, and it is the sentence that makes the 54 analysis defensible rather than incomplete. 55 56 ## Core sources 57 58 | Source | Coverage | 59 | --- | --- | 60 | [OpenCorporates](https://opencorporates.com/) | The largest open company database, ~200 jurisdictions. Best starting point for "does this company exist and where". | 61 | [Companies House](https://find-and-update.company-information.service.gov.uk/) | UK and Gibraltar. Free, complete filing history including scanned documents, and a clean API. The best-documented major registry. | 62 | [SEC EDGAR](https://www.sec.gov/edgar/search/) | All US public-company filings. Full-text searchable back to 2001 and genuinely free. | 63 | [OCCRP Aleph](https://aleph.occrp.org/) | Registries, leaks and court records in one index, with a shared entity model. The tool for cross-border work. | 64 | [OpenSanctions](https://www.opensanctions.org/) | Consolidated sanctions lists, PEP data and persons of interest, as bulk data and an API. | 65 | [ICIJ Offshore Leaks](https://offshoreleaks.icij.org/) | Panama / Paradise / Pandora Papers entities, officers and intermediaries. | 66 | [Open Ownership](https://register.openownership.org/) | Beneficial-ownership data, where it is published at all. | 67 | [BRIS](https://e-justice.europa.eu/content_find_a_company-489-en.do) | Consolidated search across most EU, Iceland, Liechtenstein and Norway registers. | 68 69 ## Key tools 70 71 ### Companies House API 72 73 The reference implementation of what a company registry ought to be: free, keyed, documented, 74 and complete back to incorporation including the scanned paper filings. Use it as the model for how 75 much you should expect elsewhere, and be disappointed accordingly. 76 77 Register at 78 [developer.company-information.service.gov.uk](https://developer.company-information.service.gov.uk/) 79 for a free key. Authentication is HTTP basic with the key as the username and an empty password — 80 note the trailing colon. 81 82 ```bash 83 export CH_KEY='your-key-here' 84 ``` 85 86 ```bash 87 # find the company and get its number, which is what everything else keys on 88 curl -s -u "$CH_KEY:" \ 89 'https://api.company-information.service.gov.uk/search/companies?q=example+trading+ltd' \ 90 | jq '.items[] | {title, company_number, company_status, address_snippet}' 91 92 # the profile: incorporation date, SIC codes, registered office, accounts due 93 curl -s -u "$CH_KEY:" \ 94 'https://api.company-information.service.gov.uk/company/12345678' \ 95 | jq '{company_name, date_of_creation, company_status, sic_codes, registered_office_address}' 96 97 # officers, including resignation dates — the sideways pivot starts here 98 curl -s -u "$CH_KEY:" \ 99 'https://api.company-information.service.gov.uk/company/12345678/officers' \ 100 | jq '.items[] | {name, officer_role, appointed_on, resigned_on, links}' 101 102 # persons with significant control: the UK's beneficial-ownership disclosure 103 curl -s -u "$CH_KEY:" \ 104 'https://api.company-information.service.gov.uk/company/12345678/persons-with-significant-control' \ 105 | jq '.items[] | {name, kind, natures_of_control, notified_on, ceased_on}' 106 107 # every other appointment this officer holds — nominee detection in one call 108 curl -s -u "$CH_KEY:" \ 109 'https://api.company-information.service.gov.uk/officers/OFFICER_ID/appointments' \ 110 | jq '{total:.total_results, items:[.items[] | .appointed_to.company_name]}' 111 112 # charges and mortgages, which name lenders the company never advertised 113 curl -s -u "$CH_KEY:" \ 114 'https://api.company-information.service.gov.uk/company/12345678/charges' \ 115 | jq '.items[] | {created_on, status, persons_entitled}' 116 117 # the filing history, then fetch the scanned document itself 118 curl -s -u "$CH_KEY:" \ 119 'https://api.company-information.service.gov.uk/company/12345678/filing-history' \ 120 | jq '.items[] | {date, type, description, doc:.links.document_metadata}' 121 122 # search officers by name across all UK companies 123 curl -s -u "$CH_KEY:" \ 124 'https://api.company-information.service.gov.uk/search/officers?q=jane+smith' \ 125 | jq '.items[] | {title, appointment_count, date_of_birth}' 126 ``` 127 128 Rate limit is 600 requests per five minutes per key; exceed it and you get HTTP 429 with a 129 `Retry-After`. The document-download host is `document-api.company-information.service.gov.uk`, not 130 the API host, and it needs the same basic auth plus an `Accept: application/pdf` header. 131 132 What it does not tell you: a PSC statement is self-declared and unverified, the 25% threshold means 133 real control can sit legally just underneath disclosure, and `date_of_birth` is published as month 134 and year only. "PSC: none" sometimes means genuinely dispersed ownership and sometimes means nobody 135 filed. 136 137 ### OpenCorporates 138 139 The aggregator that normalises ~200 jurisdictions into one schema, which is what makes it the right 140 first call when you do not yet know where a company is registered. Its value is breadth and 141 cross-jurisdiction name matching; its weakness is freshness, so confirm anything important against 142 the registry it came from. 143 144 **The API is key-gated and mostly paid.** Free keys exist for open-data projects that republish 145 under a share-alike licence, and journalists, academics and NGOs can apply for free or discounted 146 access, but the free allowance is small — of the order of 50 requests a day. Commercial plans start 147 in the low thousands of pounds a year. Without a key the API returns HTTP 401; the website search 148 remains free. 149 150 ```bash 151 export OC_TOKEN='your-api-token' 152 ``` 153 154 ```bash 155 # name search across every jurisdiction OpenCorporates holds 156 curl -s -G 'https://api.opencorporates.com/v0.4/companies/search' \ 157 --data-urlencode 'q=example trading' --data-urlencode "api_token=$OC_TOKEN" \ 158 | jq '.results.companies[].company | {name, jurisdiction_code, company_number, current_status}' 159 160 # narrow to one jurisdiction once you know it 161 curl -s -G 'https://api.opencorporates.com/v0.4/companies/search' \ 162 --data-urlencode 'q=example trading' --data-urlencode 'jurisdiction_code=gb' \ 163 --data-urlencode "api_token=$OC_TOKEN" | jq '.results.total_count' 164 165 # the canonical record, including the source URL you should cite instead 166 curl -s -G 'https://api.opencorporates.com/v0.4/companies/gb/12345678' \ 167 --data-urlencode "api_token=$OC_TOKEN" \ 168 | jq '.results.company | {name, incorporation_date, registered_address_in_full, source}' 169 170 # officers attached to that company 171 curl -s -G 'https://api.opencorporates.com/v0.4/companies/gb/12345678' \ 172 --data-urlencode "api_token=$OC_TOKEN" \ 173 | jq '.results.company.officers[].officer | {name, position, start_date, end_date}' 174 175 # search officers by name globally — the cross-border nominee sweep 176 curl -s -G 'https://api.opencorporates.com/v0.4/officers/search' \ 177 --data-urlencode 'q=jane smith' --data-urlencode "api_token=$OC_TOKEN" \ 178 | jq '.results.officers[].officer | {name, jurisdiction_code, company:.company.name}' 179 180 # every company at one address, which is how you find a formation agent 181 curl -s -G 'https://api.opencorporates.com/v0.4/companies/search' \ 182 --data-urlencode 'q=' --data-urlencode 'registered_address=*Tortola*' \ 183 --data-urlencode "api_token=$OC_TOKEN" | jq '.results.total_count' 184 185 # check your remaining allowance before a loop burns the day's quota 186 curl -s -G 'https://api.opencorporates.com/v0.4/account_status' \ 187 --data-urlencode "api_token=$OC_TOKEN" | jq '.results.account_status.usage' 188 ``` 189 190 Every company record carries a `source` object with the registry URL and the date OpenCorporates 191 scraped it. That date is the one thing you must read: a record last refreshed two years ago will 192 show a director who resigned eighteen months back as current. 193 194 ### SEC EDGAR full-text search 195 196 Every US filing since 2001, searchable by phrase. This is the one free full-text corporate archive 197 of real size, and it is the fastest way to find a private person or entity named in someone else's 198 filing — a subsidiary list, a related-party note, a beneficial-ownership schedule. 199 200 There is no API key. The identification mechanism is the `User-Agent` header, which must name your 201 application and a contact address; send a generic one and you get HTTP 403 and a short IP block. 202 The limit is ten requests per second across all `sec.gov` hosts. 203 204 ```bash 205 UA='DAEMON-SEC research you@example.com' 206 ``` 207 208 ```bash 209 # phrase search across all filings — quotes force an exact phrase 210 curl -s -A "$UA" -G 'https://efts.sec.gov/LATEST/search-index' \ 211 --data-urlencode 'q="Example Trading Limited"' \ 212 | jq '{total:.hits.total.value, hits:[.hits.hits[] | {name:._source.display_names, date:._source.file_date, id:._id}]}' 213 214 # restrict to a form type: beneficial-ownership schedules 215 curl -s -A "$UA" -G 'https://efts.sec.gov/LATEST/search-index' \ 216 --data-urlencode 'q="Example Trading"' --data-urlencode 'forms=SC 13D' \ 217 | jq '.hits.total.value' 218 219 # restrict to a date window — dateRange=custom is required alongside the dates 220 curl -s -A "$UA" -G 'https://efts.sec.gov/LATEST/search-index' \ 221 --data-urlencode 'q="going concern"' --data-urlencode 'forms=10-K' \ 222 --data-urlencode 'dateRange=custom' \ 223 --data-urlencode 'startdt=2025-01-01' --data-urlencode 'enddt=2025-06-30' \ 224 | jq '.hits.total.value' 225 226 # everything one filer said about a term, by CIK 227 curl -s -A "$UA" -G 'https://efts.sec.gov/LATEST/search-index' \ 228 --data-urlencode 'q="related party"' --data-urlencode 'entityName=0000320193' \ 229 | jq '.hits.total.value' 230 231 # page past the first ten results (the corpus caps at 10,000 total) 232 curl -s -A "$UA" -G 'https://efts.sec.gov/LATEST/search-index' \ 233 --data-urlencode 'q="Example Trading"' --data-urlencode 'from=10' \ 234 | jq '[.hits.hits[]._id]' 235 236 # a filer's complete submission index, from the structured-data host 237 curl -s -A "$UA" 'https://data.sec.gov/submissions/CIK0000320193.json' \ 238 | jq '{name, cik, formerNames, tickers, recent:[.filings.recent.form[0:5]]}' 239 240 # resolve a ticker to a CIK, which every other endpoint wants zero-padded 241 curl -s -A "$UA" 'https://www.sec.gov/files/company_tickers.json' \ 242 | jq -r 'to_entries[] | select(.value.ticker=="AAPL") | .value.cik_str' 243 244 # one XBRL concept across a company's whole history 245 curl -s -A "$UA" \ 246 'https://data.sec.gov/api/xbrl/companyconcept/CIK0000320193/us-gaap/Revenues.json' \ 247 | jq '.units["USD"] | length' 248 ``` 249 250 The `_id` in a hit is `accession-number:filename`, which reconstructs to a document URL under 251 `https://www.sec.gov/Archives/edgar/data/<cik>/<accession-no-dashes>/<filename>`. The result set is 252 capped at 10,000 and paged ten at a time, so a broad query needs narrowing by form and date rather 253 than paging. 254 255 Full-text coverage starts in 2001. Anything older is in EDGAR but only findable by filer and form, 256 not by phrase — which matters when the structure you are chasing was set up in the 1990s. 257 258 ### edgartools 259 260 A Python layer over EDGAR that parses filings into typed objects rather than handing you HTML, and 261 handles the `User-Agent` requirement and rate limiting for you. Use it the moment you need more 262 than a handful of filings, and particularly for Form 4 insider transactions and 13F holdings, where 263 the raw XML is tedious and the parsing is where the mistakes happen. 264 265 ```bash 266 pip install edgartools 267 ``` 268 269 ```python 270 from edgar import Company, set_identity, get_filings 271 272 set_identity("you@example.com") # required; this becomes the User-Agent 273 274 c = Company("AAPL") 275 276 # the filing index for one form type 277 c.get_filings(form="10-K").head(5) 278 279 # insider transactions as structured objects, not XML 280 c.get_filings(form="4").latest().obj() 281 282 # institutional holdings from a 13F, already parsed into positions 283 get_filings(form="13F-HR").latest().obj().holdings 284 285 # subsidiary and related-party text out of the latest annual report 286 tenk = c.get_filings(form="10-K").latest().obj() 287 print(tenk["Item 1"][:2000]) 288 289 # one XBRL concept as a DataFrame, for a time series 290 c.get_facts().query().by_concept("Revenues").to_dataframe() 291 292 # filings across all companies in a quarter, to sweep a form type 293 get_filings(year=2025, quarter=1, form="SC 13D") 294 ``` 295 296 `set_identity` is not optional — without it the library refuses to call EDGAR, which is the correct 297 behaviour. For bulk retrieval of raw documents rather than parsed objects, 298 `sec-edgar-downloader` is the simpler tool: `Downloader("YourOrg", "you@example.com")` then 299 `dl.get("10-K", "AAPL", after="2020-01-01", limit=5)`. 300 301 ### OpenSanctions 302 303 Consolidated sanctions designations, politically-exposed-person lists and persons of interest from 304 several hundred sources, normalised into one entity model. Run every name you extract from a 305 registry through it, because a designation changes the legal meaning of the whole structure. 306 307 The API is metered pay-as-you-go, with **free keys available on request for journalism, 308 civil-society and academic work**. The full dataset is also published for download under a 309 share-alike licence, and the matching service is open source as 310 [yente](https://github.com/opensanctions/yente), which you can self-host with no key at all — the 311 right choice when the names you are screening should not leave your machine. 312 313 ```bash 314 export OS_API_KEY='your-key' 315 ``` 316 317 ```bash 318 # free-text search across the default collection 319 curl -s -H "Authorization: ApiKey $OS_API_KEY" -G \ 320 'https://api.opensanctions.org/search/default' --data-urlencode 'q=Ilham Aliyev' \ 321 | jq '.results[] | {id, caption, schema, datasets, topics}' 322 323 # restrict to companies rather than people 324 curl -s -H "Authorization: ApiKey $OS_API_KEY" -G \ 325 'https://api.opensanctions.org/search/default' \ 326 --data-urlencode 'q=Example Trading' --data-urlencode 'schema=Company' \ 327 | jq '.total.value' 328 329 # structured matching, which scores candidates instead of string-matching 330 curl -s -H "Authorization: ApiKey $OS_API_KEY" -X POST \ 331 -H 'Content-Type: application/json' \ 332 'https://api.opensanctions.org/match/default' \ 333 -d '{"queries":{"q1":{"schema":"Person","properties":{"name":["Jane Smith"],"birthDate":["1970"],"nationality":["gb"]}}}}' \ 334 | jq '.responses.q1.results[] | {score, caption, topics}' 335 336 # the full entity, including every alias, address and linked entity 337 curl -s -H "Authorization: ApiKey $OS_API_KEY" \ 338 'https://api.opensanctions.org/entities/NK-ENTITY-ID' | jq '.properties' 339 340 # what datasets a hit came from, which is how you cite the designation 341 curl -s -H "Authorization: ApiKey $OS_API_KEY" \ 342 'https://api.opensanctions.org/datasets' | jq '.datasets[] | {name, title, entity_count}' 343 344 # self-hosted yente takes the same paths with no key 345 curl -s -G 'http://localhost:8000/search/default' --data-urlencode 'q=Jane Smith' | jq '.total' 346 ``` 347 348 A match is a match on *data*, not an identification. Common names produce confident-looking hits on 349 unrelated people, and the sanctions lists themselves contain transliteration variants of one person 350 as separate entries. Always open the entity, read the aliases and birth date, and cite the 351 underlying designation — the OFAC or EU legal act — not the aggregator. 352 353 ### OCCRP Aleph 354 355 Registries, leaks, court records, procurement data and gazettes in one index, all mapped onto the 356 FollowTheMoney entity schema. That shared schema is the point: a `Company` from a Latvian registry 357 and a `Company` from a leaked corporate database have the same property names, so you can ask one 358 query across both. 359 360 API keys come with an Aleph account; some collections need separate permission and investigative 361 collections are not public. The header format is `Authorization: ApiKey <key>`, and all paths sit 362 under `/api/2/`. 363 364 ```bash 365 export ALEPH_KEY='your-api-key' 366 H="Authorization: ApiKey $ALEPH_KEY" 367 ``` 368 369 ```bash 370 # free-text search across every collection you can see 371 curl -s -H "$H" -G 'https://aleph.occrp.org/api/2/entities' \ 372 --data-urlencode 'q=Example Trading Limited' \ 373 | jq '.results[] | {id, schema, caption, collection:.collection.label}' 374 375 # restrict by entity type — the schema names are the FollowTheMoney ones 376 curl -s -H "$H" -G 'https://aleph.occrp.org/api/2/entities' \ 377 --data-urlencode 'q=Jane Smith' --data-urlencode 'filter:schema=Person' \ 378 | jq '.total' 379 380 # restrict to one collection, once you know which dataset matters 381 curl -s -H "$H" -G 'https://aleph.occrp.org/api/2/entities' \ 382 --data-urlencode 'q=Example Trading' --data-urlencode 'filter:collection_id=123' \ 383 | jq '.total' 384 385 # one entity in full, with every property the schema allows 386 curl -s -H "$H" 'https://aleph.occrp.org/api/2/entities/ENTITY_ID' | jq '.properties' 387 388 # what this entity is connected to and how — ownership, directorship, payment 389 curl -s -H "$H" -G 'https://aleph.occrp.org/api/2/entities/ENTITY_ID/expand' \ 390 --data-urlencode 'limit=50' \ 391 | jq '.results[] | {property, count, entities:[.entities[].caption]}' 392 393 # the entity-model definitions, so you know which properties exist to filter on 394 curl -s 'https://aleph.occrp.org/api/2/metadata' \ 395 | jq '.schemata | keys | map(select(. | test("Company|Ownership|Person|Directorship")))' 396 397 # list the collections your key can reach, with their ids and update dates 398 curl -s -H "$H" -G 'https://aleph.occrp.org/api/2/collections' --data-urlencode 'limit=50' \ 399 | jq '.results[] | {id, label, category, updated_at}' 400 ``` 401 402 The schema is what makes Aleph worth the learning curve. `Company` and `Person` are the nodes; 403 `Ownership`, `Directorship`, `Membership` and `Payment` are *intermediate entities* with their own 404 properties — an `Ownership` carries a percentage, a start date and an end date, and connects an 405 owner to an asset. `/expand` walks those edges, which is how you traverse a chain without reading 406 every document. 407 408 Leaked collections are snapshots. An `Ownership` from a 2016 leak describes 2016, and saying so is 409 the difference between a finding and a libel risk. 410 411 ### ICIJ Offshore Leaks 412 413 Entities, officers, intermediaries and addresses from the Panama, Paradise, Pandora, Bahamas and 414 Offshore Leaks investigations. Web-only, no API, and worth a walkthrough because the structure of 415 the database is not obvious from the search box. 416 417 Search at [offshoreleaks.icij.org](https://offshoreleaks.icij.org/) by company name, person name or 418 address. Read the result in this order. 419 420 ```text 421 Entity the offshore company itself: jurisdiction, incorporation and inactivation 422 dates, and the leak it came from. The jurisdiction plus the dates is what 423 you take back to that jurisdiction's registry 424 Officers the people and companies attached, each with a role (shareholder, director, 425 beneficiary, nominee). "Nominee" here is explicit, which is rarer than it 426 sounds 427 Intermediary the law firm or agent that formed it. This is the strongest pivot in the 428 database — the intermediary's other clients are listed, and a pattern of 429 one agent forming a cluster of companies is a structure 430 Addresses search by address, not name, when a name is too common. A residential 431 address shared by forty companies is the finding 432 Linked the graph view, which shows the chain between two entities if one exists 433 ``` 434 435 Capture the node URL for every entity and officer, the leak name, and the date range the data 436 covers. The URLs are stable and citable. 437 438 Two limits to state every time you use it: being in the database is not evidence of wrongdoing — 439 offshore structures are legal and ICIJ says so prominently — and the data is as of the leak, which 440 for Panama means 2015. A company shown as active was active then. 441 442 ### Jurisdiction-by-jurisdiction fallbacks 443 444 When the chain crosses a border, what you can get changes completely. These are the sources worth 445 knowing before you conclude a jurisdiction publishes nothing. 446 447 | Source | What it adds | 448 | --- | --- | 449 | [BRIS / e-Justice](https://e-justice.europa.eu/content_find_a_company-489-en.do) | One search box over most EU registers. Coverage per country varies from full filings to name-and-number only. | 450 | [North Data](https://northdata.com) | EU registers with relationship graphs and German trade-register notices, which often name shareholders the registry does not. | 451 | [Open Ownership Register](https://register.openownership.org/) | Beneficial-ownership declarations consolidated across the countries that publish them. | 452 | [RuPEP](https://rupep.org/en/) | Politically exposed persons in Russia, Belarus, Kazakhstan, Kyrgyzstan, Georgia and Moldova, with family and associate links. | 453 | [SanctionsExplorer](https://sanctionsexplorer.org/) | Historical OFAC, UN and EU designations, including delisted ones — which is what you need for a structure that predates a current list. | 454 | [ImportYeti](https://www.importyeti.com/) | US customs sea-shipment records: who ships to whom, which evidences a trading relationship no registry records. | 455 | [Wikipedia's register list](https://en.wikipedia.org/wiki/List_of_official_business_registers) | The maintained index of official registers worldwide. Start here for a jurisdiction you have not worked before. | 456 457 ## Reading the structure 458 459 - **Nominee directors** appear on dozens or hundreds of companies. A director with 200 appointments 460 is a service provider, not a decision-maker, and the Companies House appointments endpoint tells 461 you which you have in one call. 462 - **Registered-address clustering** usually means a formation agent. Search the address, not the 463 name, and the agent's whole book appears. 464 - **Shareholders that are themselves companies** are the chain you have to walk. Keep going until 465 you hit a natural person or a jurisdiction that will not tell you, then record which. 466 - **Charges and mortgages** name lenders, which reveals banking relationships the company did not 467 advertise and gives you a regulated counterparty who had to do their own due diligence. 468 - **Dates are the load-bearing part.** An ownership that ended before the event you are 469 investigating is not relevant, and a leak snapshot has one date for everything in it. 470 471 ## Tool reference 472 473 | Tool | What it does | Cost | 474 | --- | --- | --- | 475 | [527 Explorer](https://projects.propublica.org/527-explorer/) | ProPublica's 527 Explorer is a database that allows users to examine the finances of organizations known as 527s in the United States, which can raise… | free | 476 | [BlockExplorer](https://blockexplorer.com/) | Following a bitcoin trail or following a bitcoin account? | free | 477 | [Companies House](https://find-and-update.company-information.service.gov.uk/) | Search companies and individuals in the United Kingdom and Gibraltar. | free | 478 | [EDGAR Command Line Interface (edgar-tool)](https://pypi.org/project/edgar-tool/) | Tool for the retrieval of corporate and financial data from SEC's EDGAR (Electronic Data Gathering, Analysis, and Retrieval) database. | free | 479 | [EDGAR](https://www.sec.gov/edgar/search/) | Database of corporate filings for the US | free | 480 | [Etherscan](https://etherscan.io/) | An explorer that allows researchers to track wallets, transactions and more on the Ethereum blockchain. | free | 481 | [EU consolidated corporate registers (BRIS)](https://e-justice.europa.eu/content_find_a_company-489-en.do) | Consolidated company registers covering most of the EU, Iceland, Liechtenstein and Norway. | free | 482 | [EU Sanctions Map](https://www.sanctionsmap.eu/) | Database of sanctions imposed by the European Union and the United Nations | free | 483 | [Global Suppliers Online](https://www.globalsuppliersonline.com/) | A site dedicated to connect suppliers and buyers of goods from all over the world. | partly free | 484 | [ICIJ Offshore Leaks Database](http://offshoreleaks.icij.org/) | Find out who’s behind more than 810k offshore companies, foundations and trusts from the Panama Papers, the Offshore Leaks, the Bahamas Leaks and the… | free | 485 | [ImportGenius](https://www.importgenius.com/) | Commercial supplier of trade data for 23 countries. Paid service but journalists can ask for free access. | paid | 486 | [ImportYeti](https://www.importyeti.com/) | Search 60 million US customs sea shipment records, find company suppliers. | free | 487 | [LittleSis](https://littlesis.org/database) | Connects the dots between influential / wealthy individuals in (mostly US) politics and business. | free | 488 | [Lumen](https://lumendatabase.org/) | A research project collecting and publishing legal takedown notices for online content transparency | free | 489 | [North Data](https://northdata.com) | Search for people and companies in EU corporate and trade registers + visualize relationships | partly free | 490 | [OpenSecrets](https://www.opensecrets.org/) | Data on campaign finance, lobbying, and spending in U.S. politics | free | 491 | [OSINT Tools Map](https://cybdetective.com/osintmap/) | An interactive map serving as a curated archive of country-specific OSINT resources, including business registries, court records, and cadastral maps… | free | 492 | [RuPEP](https://rupep.org/en/) | Online database of politically exposed persons in Russia, Belarus, Kyrgyzstan, Kazakhstan, Georgia and Moldova. | free | 493 | [SanctionsExplorer](https://sanctionsexplorer.org/) | A comprehensive database of current and historical OFAC/UN/EU sanctions | free | 494 | [UN Comtrade Database](https://comtradeplus.un.org/) | United Nations free database of global trade. | free | 495 | [Wikipedia list of company registers](https://en.wikipedia.org/wiki/List_of_official_business_registers) | A list of official business registers around the world. | free | 496 | China-related resources | Resources for research on companies in China. | — | 497 | OpenSanctions | Open-source international database of sanctions data, persons of interest and politically exposed persons. | partly free | 498 499 ## Pitfalls 500 501 - **Registry data is self-reported** and frequently not verified by anyone. A filed address may be 502 fictional. 503 - **"Beneficial owner" is defined differently everywhere**, and thresholds (often 25%) let real 504 control sit just underneath the disclosure line. 505 - **Aggregators lag.** For anything current, go to the registry itself. 506 - **Name collisions across jurisdictions** are constant. Always carry the registration number. 507 - **Dissolved does not mean gone.** Historical filings often hold what you need, and some registries 508 purge them after a few years — capture early. 509 510 ## Worked example 511 512 One datum: the name "Northgate Minerals Trading" on an invoice. The company, the numbers and the 513 returns are invented; the order of the pivots and what each source can and cannot settle are not. 514 515 ```bash 516 # 1. where does it exist at all 517 curl -s -G 'https://api.opencorporates.com/v0.4/companies/search' \ 518 --data-urlencode 'q=Northgate Minerals Trading' --data-urlencode "api_token=$OC_TOKEN" \ 519 | jq '.results.companies[].company | {name, jurisdiction_code, company_number, current_status}' 520 # two hits: gb/09876543 (active) and vg/1654321 (OpenCorporates record, source dated 2019) 521 ``` 522 523 A UK company and a British Virgin Islands company with the same name. The UK one is where the data 524 is, so start there and carry the number `09876543`. 525 526 ```bash 527 # 2. who is declared to control it 528 curl -s -u "$CH_KEY:" \ 529 'https://api.company-information.service.gov.uk/company/09876543/persons-with-significant-control' \ 530 | jq '.items[] | {name, kind, natures_of_control}' 531 # one PSC, kind "corporate-entity-person-with-significant-control", 532 # name "Northgate Holdings Ltd", country of registration "Virgin Islands, British" 533 ``` 534 535 The declared controller is the BVI company, so UK disclosure has handed the chain straight back 536 offshore. That is the expected outcome, and worth stating as one. 537 538 ```bash 539 # 3. the officers, and whether they are real or nominal 540 curl -s -u "$CH_KEY:" \ 541 'https://api.company-information.service.gov.uk/company/09876543/officers' \ 542 | jq '.items[] | {name, officer_role, appointed_on, id:.links.officer.appointments}' 543 # two directors; take each appointments link 544 curl -s -u "$CH_KEY:" \ 545 'https://api.company-information.service.gov.uk/officers/AbC123.../appointments' | jq '.total_results' 546 # 147 547 ``` 548 549 147 appointments makes that director a formation-agent nominee, not a decision-maker. The other has 550 three, all in the same group — that is the person to follow. 551 552 ```bash 553 # 4. screen both names and the BVI entity 554 curl -s -H "Authorization: ApiKey $OS_API_KEY" -G \ 555 'https://api.opensanctions.org/search/default' --data-urlencode 'q=Northgate Holdings' \ 556 | jq '.results[] | {caption, schema, topics, datasets}' 557 # no designation; one PEP-adjacent hit on a similarly-named Cyprus entity — not the same company 558 ``` 559 560 A near-miss on a different entity is exactly the false positive to discard explicitly, in writing, 561 so it does not resurface later as a claim. 562 563 ```bash 564 # 5. the offshore end, where the registry publishes nothing 565 curl -s -H "Authorization: ApiKey $ALEPH_KEY" -G 'https://aleph.occrp.org/api/2/entities' \ 566 --data-urlencode 'q=Northgate Holdings' --data-urlencode 'filter:schema=Company' \ 567 | jq '.results[] | {id, caption, collection:.collection.label}' 568 # a hit in an ICIJ collection; expand it for the ownership edges 569 curl -s -H "Authorization: ApiKey $ALEPH_KEY" -G \ 570 'https://aleph.occrp.org/api/2/entities/ENTITY_ID/expand' --data-urlencode 'limit=50' \ 571 | jq '.results[] | {property, entities:[.entities[].caption]}' 572 # Ownership -> a named individual, percentage 100, startDate 2014 573 ``` 574 575 Cross-checking that individual in [ICIJ Offshore Leaks](https://offshoreleaks.icij.org/) gives the 576 same person as beneficiary via the same BVI intermediary, with a residential address shared by 577 eleven other companies — a second, independent confirmation of the same edge. 578 579 ```bash 580 # 6. does the name appear in anyone's US filings 581 curl -s -A "$UA" -G 'https://efts.sec.gov/LATEST/search-index' \ 582 --data-urlencode 'q="Northgate Minerals Trading"' \ 583 | jq '.hits.hits[] | {name:._source.display_names, date:._source.file_date}' 584 # one 10-K exhibit, 2023, listing it as a counterparty of a listed miner 585 ``` 586 587 What you can assert: invoice name → UK company 09876543 (Companies House, retrieved with date) → 588 corporate PSC in BVI (UK filing, self-declared) → named individual with 100% ownership from 2014 589 (Aleph, ICIJ collection, snapshot date stated) → confirmed independently in the ICIJ public 590 database via the same intermediary → named as a counterparty in a 2023 SEC exhibit. Six sources, 591 two of them independent of each other on the key link. 592 593 What you still cannot say: whether that individual controls it *today*. The ownership edge is from 594 a leak snapshot, the BVI publishes nothing current, and the UK PSC declaration names the company 595 rather than the person. "Beneficial ownership is not currently published in the British Virgin 596 Islands; the most recent evidenced owner is X as of 2014" is the honest sentence, and it is a 597 stronger finding than an unqualified assertion. 598 599 What would falsify it: a later primary filing naming a different beneficial owner, the Aleph and 600 ICIJ records resolving to different entities once registration numbers are compared, or the SEC 601 exhibit referring to a namesake rather than company 09876543. The 2014 ownership edge is the 602 oldest and weakest link; date it explicitly and replace it when a newer primary record appears. 603 604 ## Broader catalogues 605 606 - [Public Records OSINT](https://tools.osintnewsletter.com/tool-categories/public-records-osint) 607 - [Blockchain/Cryptocurrency OSINT](https://tools.osintnewsletter.com/tool-categories/blockchain-and-cryptocurrency-osint) 608 609 610 ## More tools 611 612 Further tools for this area from the OSINT Newsletter Tools Library ([Blockchain/Cryptocurrency OSINT](https://tools.osintnewsletter.com/tool-categories/blockchain-and-cryptocurrency-osint)), excluding those already listed above. 613 614 | Tool | What it does | 615 | --- | --- | 616 | [Arkham Intel](https://intel.arkm.com/) | A blockchain intelligence and analytics platform that de-anonymizes cryptocurrency transactions. | 617 | [Bid Detail](https://www.biddetail.com/) | A procurement intelligence platform that makes government contract and tender data searchable. | 618 | [Bitbo](https://bitbo.io/) | A Bitcoin data dashboard that tracks price, market, mining and on-chain metrics. | 619 | [Bitcoin Talk](https://bitcointalk.org/) | A long-running online discussion forum focused on Bitcoin, cryptocurrencies, blockchain technology and related projects. | 620 | [Bitcoin Whoswho](https://www.bitcoinwhoswho.com/) | Cryptocurrency intelligence tool used to investigate Bitcoin addresses and identify reported scams. | 621 | [Block Explorer](https://www.blockexplorer.com/) | A blockchain search engine that lets you inspect cryptocurrency transactions, wallet addresses, blocks, and network activity. | 622 | [Dune](https://dune.com/home) | A blockchain analytics platform that lets you explore and analyse data from cryptocurrencies and decentralised applications. | 623 | [GuideStar](https://www.guidestar.org/) | A nonprofit intelligence platform that provides detailed information on registered charities and nonprofit organisations… | 624 | [TheBigBrother](https://github.com/chadi0x/TheBigBrother) | All-in-one OSINT toolkit that helps track usernames across the web, investigate emails and domains, extract metadata, and follow… | 625 626 ## Sources 627 628 Both catalogues below are maintained by other people and are considerably larger than 629 this page. Use them as the canonical index; this sheet is a working route through them. 630 631 - [Bellingcat's Online Investigation Toolkit](https://bellingcat.gitbook.io/toolkit) — ~340 tools, each with its own 632 review page covering cost, difficulty, requirements and limitations. 633 - [OSINT Newsletter Tools Library](https://tools.osintnewsletter.com) — ~280 tools, organised by investigative goal. 634 635 Neither publishes a licence, so nothing here is copied from them: tool names, one-line 636 descriptions, cost flags and links are catalogue facts, and the method and commentary are 637 this site's own. See [credits](/credits).