Skip to main content

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

Headers

Content-Type: application/json

Body Parameters

query
string
Company name or search query. Either query, companyNumber, or ticker is required.Example: "Apple Inc"
companyNumber
string
Specific company registration number (UK Companies House or CIK for SEC).Example: "00000789"
ticker
string
Stock ticker symbol (US companies only).Example: "AAPL"
country
string
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
object
Progress update during search
result
object
Partial result from a data source
complete
object
Final complete result with all data sources
error
object
Error event

Complete Result Structure

CompanyAnalysisResult
object

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"
}
500
Request failed
{
  "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

Coverage: All UK registered companiesData includes:
  • Company registration details
  • Directors and officers
  • Filings and accounts
  • Charges and insolvency
  • SIC codes
Requires: API key

Best Practices

Recommendations

  1. Specify country: Set correct country parameter for better results
  2. Use ticker for speed: US ticker lookups are faster than name searches
  3. Handle partial results: Some data sources may fail or timeout
  4. Cache results: Company data changes infrequently
  5. 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;
}

Build docs developers (and LLMs) love