Skip to main content
Topograph offers a powerful search API to find companies across multiple countries. The search endpoint allows to find companies based on two main search criteria.
  1. Company name: legal name, commercial name, or historical name
  2. Company number: registration number, tax number, or VAT number
Note that the precise way search methods work can vary depending on the country you’re searching in.

Response Times

Search response times vary based on the specific register we need to query.
  • Fastest responses: A few hundred milliseconds
  • Slowest responses: Up to ten seconds
For a detailed breakdown of:
  • Available search methods by country
  • Expected response times for each country
  • Other country-specific search information
Please refer to our comprehensive Coverage Map as well as the Country Specifics page.

Search Endpoint

Standard Request
curl --request GET \
  --url 'https://api.topograph.co/v2/search?country=FR&query=Topograph' \
  --header 'x-api-key: <api-key>'
Streaming Request
curl --request GET \
  --url 'https://api.topograph.co/v2/search?country=DE&query=BMW&stream=true' \
  --header 'x-api-key: <api-key>' \
  --header 'Accept: text/event-stream' \
  --no-buffer

Query Parameters

ParameterRequiredDescription
countryYesCountry code for the search. Can be an ISO country code (e.g., “FR”, “GB”, “DE”). For US states and Canada provinces, combine “US” or “CA” with the state code (e.g., “US-CA” for California).
queryYesThe search term - can be a company name or company number.
streamNoEnable streaming mode (true or false). When enabled, returns Server-Sent Events with progressive results. Default: false.

Standard Response

The search results include basic company information such as:
  • Legal name (and English translation for non-Latin names)
  • Registration number and/or tax number
  • Legal address
  • Country code
Example response (standard mode):
[
  {
    "id": "932884117",
    "legalName": "SEMAPHORE",
    "legalNameInEnglish": null,
    "countryCode": "FR",
    "address": {
      "addressLine1": "10 rue de la Fraternité",
      "city": "Bagnolet",
      "postalCode": "93170",
      "state": "Île-de-France",
      "countryCode": "FR"
    }
  }
]

Streaming Mode

For countries where multiple search sources exist, you can enable streaming mode to receive results progressively as each source completes. This significantly reduces time-to-first-result.

How to Use Streaming

Add the stream=true query parameter and set the Accept header to text/event-stream:
Request
curl --request GET \
  --url 'https://api.topograph.co/v2/search?country=DE&query=BMW&stream=true' \
  --header 'x-api-key: <api-key>' \
  --header 'Accept: text/event-stream' \
  --no-buffer

Streaming Response Format

The endpoint returns Server-Sent Events (SSE) with named events: Progress Event - Partial results as sources complete:
event: progress
data: {"results":[{"id":"DE123456","legalName":"Company A","countryCode":"DE","address":{...}}]}
Complete Event - Final results (all sources finished):
event: complete
data: {"results":[{"id":"DE123456","legalName":"Company A",...},{"id":"DE789012","legalName":"Company B",...}]}
Error Event - If search fails:
event: error
data: {"error":"Error message"}

When to Use Streaming

Use streaming when:
  • You want the fastest time-to-first-result
  • You’re building interactive UIs that can display partial results
  • You’re searching in countries with multiple search sources
Use standard mode when:
  • You need all results before processing
  • You’re doing batch operations
  • Simpler integration is preferred

Client-Side Example

Using modern async/await with fetch and ReadableStream:
async function streamSearch(country, query) {
  const response = await fetch(
    `https://api.topograph.co/v2/search?country=${country}&query=${query}&stream=true`,
    {
      headers: {
        'x-api-key': 'your-api-key',
        Accept: 'text/event-stream',
      },
    },
  );

  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';

  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;

      buffer += decoder.decode(value, { stream: true });
      const lines = buffer.split('\n');
      buffer = lines.pop(); // Keep incomplete line in buffer

      let currentEvent = '';
      for (const line of lines) {
        if (line.startsWith('event:')) {
          currentEvent = line.slice(7).trim();
        } else if (line.startsWith('data:')) {
          const data = JSON.parse(line.slice(6));

          if (currentEvent === 'progress') {
            console.log(`Progress: ${data.results.length} results`);
            updateUI(data.results); // Update UI progressively
          } else if (currentEvent === 'complete') {
            console.log(`Complete: ${data.results.length} total results`);
            updateUI(data.results); // Final update
            return data.results; // Exit loop
          } else if (currentEvent === 'error') {
            throw new Error(data.error);
          }
        }
      }
    }
  } finally {
    reader.releaseLock();
  }
}

// Usage
try {
  const results = await streamSearch('DE', 'BMW');
  console.log('Final results:', results);
} catch (error) {
  console.error('Search failed:', error);
}
Alternative using EventSource API (simpler but less control):
const eventSource = new EventSource(
  'https://api.topograph.co/v2/search?country=DE&query=BMW&stream=true',
  {
    headers: { 'x-api-key': 'your-api-key' },
  },
);

eventSource.addEventListener('progress', (e) => {
  const { results } = JSON.parse(e.data);
  console.log(`Progress: ${results.length} results`);
  updateUI(results);
});

eventSource.addEventListener('complete', (e) => {
  const { results } = JSON.parse(e.data);
  console.log(`Complete: ${results.length} results`);
  updateUI(results);
  eventSource.close();
});

eventSource.addEventListener('error', (e) => {
  console.error('Error:', JSON.parse(e.data).error);
  eventSource.close();
});

Result Ordering

Search results are ordered by relevance and search method priority. If the query contains or matches an exact company registration ID (based on the country’s format), results from direct ID searches will appear at the top. This ensures precise matches are prioritized over broader name-based searches. Other results (from name searches, VAT-derived, or agentic methods) follow in descending order of specificity.
The company number format may vary by country. For example, in Germany it is a concatenation of the register and city (e.g., “Augsburg HRB 34617”). The search function will always return a usable company number that can be used with other endpoints and features of Topograph.
Once you have found a company through the search endpoint, you can use its ID to retrieve more detailed information using the Company Data endpoint.