Overview
The Company Analysis API searches multiple official company registries and databases:
- UK Companies House: UK company registrations, officers, and filings
- GLEIF LEI: Global Legal Entity Identifier database
- SEC EDGAR: US Securities and Exchange Commission filings
This endpoint uses Server-Sent Events (SSE) streaming to provide real-time results as each data source responds.
UK Companies House API requires COMPANIES_HOUSE_API_KEY environment variable.
Endpoint
POST /api/company/analyze
Request
Content-Type: application/json
Body Parameters
Company name or search query. Either query, companyNumber, or ticker is required.Example: "Apple Inc"
Specific company registration number (UK Companies House or CIK for SEC).Example: "00000789"
Stock ticker symbol (US companies only).Example: "AAPL"
Target country for registry search. Determines which data sources to query.Valid values: "US", "UK"Default: "US"
"UK": Searches Companies House and GLEIF
"US": Searches SEC EDGAR and GLEIF
Request Example
curl -X POST http://localhost:3000/api/company/analyze \
-H "Content-Type: application/json" \
-d '{
"query": "Apple Inc",
"ticker": "AAPL",
"country": "US"
}'
Response
The endpoint returns a Server-Sent Events (SSE) stream with Content-Type: text/event-stream.
Event Types
Progress update during search
Current step (e.g., “Searching UK Companies House”)
Data source: "companiesHouse", "gleif", or "secEdgar"
Partial result from a data source
Partial results from one data source
Final complete result with all data sources
See complete result structure below
Complete Result Structure
UK Companies House
UK company registry data (only for country: “UK”)
Search results matching the queryEach result:{
company_number: string,
title: string,
company_status: string,
company_type: string,
date_of_creation?: string,
address_snippet?: string
}
Full company details (first match)Show CompaniesHouseCompany properties
Status (“active”, “dissolved”, etc.)
Type (“ltd”, “plc”, etc.)
registered_office_address
Registered address
Standard Industrial Classification codes
Accounting information and deadlines
Whether company has charges registered
Company officers (directors, secretaries)Each officer:{
name: string,
officer_role: string,
appointed_on?: string,
resigned_on?: string,
nationality?: string,
country_of_residence?: string,
occupation?: string,
date_of_birth?: { month: number, year: number }
}
Recent company filingsEach filing:{
category: string,
date: string,
description: string,
type: string
}
GLEIF LEI Database
Global Legal Entity Identifier data (always included)
LEI records matching the queryEach record:{
lei: string, // Legal Entity Identifier
entity: {
legalName: { name: string, language?: string },
legalAddress: {
addressLines: string[],
city: string,
country: string,
postalCode?: string
},
jurisdiction?: string,
category?: string,
status: string
},
registration: {
initialRegistrationDate: string,
lastUpdateDate: string,
status: string,
managingLou: string
}
}
SEC EDGAR
US SEC filings data (only for country: “US”)
Search resultsEach result:{
cik: string, // Central Index Key
name: string,
tickers?: string[]
}
Full company detailsShow SecEdgarCompany properties
Standard Industrial Classification
Fiscal year end (MMDD format)
Recent SEC filingsEach filing:{
accessionNumber: string,
filingDate: string,
reportDate?: string,
form: string, // e.g., "10-K", "8-K", "10-Q"
primaryDocument?: string,
items?: string,
size?: number
}
Errors
Errors from individual data sources (omitted if no errors){
companiesHouse?: string,
gleif?: string,
secEdgar?: string
}
Response Example
{
"type": "progress",
"data": {
"step": "Searching SEC EDGAR",
"source": "secEdgar",
"total": 2,
"completed": 1
}
}
Error Responses
400
Required parameter missing
{
"success": false,
"error": "Company name, number, or ticker is required"
}
{
"success": false,
"error": "Request failed"
}
Configuration
For UK Companies House access:
# Optional: UK Companies House API key
COMPANIES_HOUSE_API_KEY=your_companies_house_key
Source Code Reference
- API Route:
source/app/api/company/analyze/route.ts:15
- Companies House:
source/lib/company/companies-house.ts
- SEC EDGAR:
source/lib/company/sec-edgar.ts
- GLEIF:
source/lib/company/gleif.ts
- Type Definitions:
source/lib/company/types.ts
Data Source Coverage
UK (Companies House)
US (SEC EDGAR)
Global (GLEIF)
Coverage: All UK registered companiesData includes:
- Company registration details
- Directors and officers
- Filings and accounts
- Charges and insolvency
- SIC codes
Requires: API key Coverage: US public companiesData includes:
- Company information
- Stock tickers
- SEC filings (10-K, 10-Q, 8-K, etc.)
- Business address
- SIC classification
Requires: No API key Coverage: 2+ million global entitiesData includes:
- Legal Entity Identifiers (LEI)
- Legal names and addresses
- Jurisdiction and status
- Registration dates
Requires: No API key
Best Practices
Recommendations
- Specify country: Set correct
country parameter for better results
- Use ticker for speed: US ticker lookups are faster than name searches
- Handle partial results: Some data sources may fail or timeout
- Cache results: Company data changes infrequently
- Check errors field: Individual sources may fail without blocking others
Example Implementation
interface CompanySummary {
name: string;
country: string;
status: string;
officers?: string[];
lei?: string;
filings?: number;
}
async function searchCompany(query: string, country: 'US' | 'UK'): Promise<CompanySummary> {
const response = await fetch('/api/company/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country })
});
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let result: any;
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value);
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const event = JSON.parse(line.slice(6));
if (event.type === 'complete') {
result = event.data.result;
}
}
}
}
// Build summary
const summary: CompanySummary = {
name: query,
country,
status: 'unknown',
officers: [],
filings: 0
};
if (country === 'UK' && result.companiesHouse?.company) {
const ch = result.companiesHouse;
summary.name = ch.company.company_name;
summary.status = ch.company.company_status;
summary.officers = ch.officers?.map((o: any) => o.name) ?? [];
summary.filings = ch.filings?.length ?? 0;
} else if (country === 'US' && result.secEdgar?.company) {
const sec = result.secEdgar;
summary.name = sec.company.name;
summary.status = 'active'; // SEC only lists active companies
summary.filings = sec.recentFilings?.length ?? 0;
}
if (result.gleif?.records?.[0]) {
summary.lei = result.gleif.records[0].lei;
}
return summary;
}