Address Search

Find companies at a specific address by combining the /api/cities lookup with search filters (cityName, streetName, postalCode). Street names support prefix matching; city and postal code require exact values from the database.

How It Works

  1. Look up a city - Call the /api/cities endpoint with a search term to find the exact city name
  2. Build your address filter - Combine the city name with optional street name and postal code
  3. Search for companies - Call /api/company/search with your address filters to find matching companies
  4. Paginate results - Use page and pageSize to navigate through large result sets

Try Address Search

Don't have an API key? Get your API key →

Type at least 2 characters to search cities

Enter a country code and optionally a city, street, or postal code, then click "Search Companies"

TypeScript Implementation

GET
/api/company/search
// Address Search - works in Node.js 18+ and browsers
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://app.companydata.com/api';

interface City {
  cityName: string;
}

interface CompanyResult {
  ID: string;
  'Company Name': string;
  'Address 1'?: string;
  'City'?: string;
  'Postal Code'?: string;
  'Country Name'?: string;
  [key: string]: any;
}

interface SearchResponse {
  data: {
    records: CompanyResult[];
    totalCount: number;
  };
}

interface CityResponse {
  data: City[];
}

async function fetchApi<T>(endpoint: string, params: Record<string, string | number>): Promise<T> {
  const url = new URL(`${BASE_URL}/${endpoint}`);
  Object.entries(params).forEach(([key, value]) => {
    if (value !== undefined && value !== '' && value !== null) {
      url.searchParams.append(key, String(value));
    }
  });

  const response = await fetch(url.toString(), {
    headers: { 'x-api-key': API_KEY },
  });

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${await response.text()}`);
  }

  return response.json();
}

// Step 1: Look up cities by name
async function lookupCities(search: string, countryCode?: string): Promise<City[]> {
  if (search.length < 2) return [];

  const params: Record<string, string> = { search };
  if (countryCode) params.countries = countryCode;

  const response = await fetchApi<CityResponse>('cities', params);
  return response.data || [];
}

// Step 2: Search companies by address
async function searchByAddress(options: {
  countryCode: string;
  cityName?: string;
  streetName?: string;
  postalCode?: string;
  page?: number;
  pageSize?: number;
}): Promise<{ records: CompanyResult[]; totalCount: number }> {
  const params: Record<string, string | number> = {
    countryCode: options.countryCode,
    statusCode: '0,1',
    page: options.page || 1,
    pageSize: options.pageSize || 25,
  };

  if (options.cityName) params.cityName = options.cityName;
  if (options.streetName) params.streetName = options.streetName;
  if (options.postalCode) params.postalCode = options.postalCode;

  const response = await fetchApi<SearchResponse>('company/search', params);

  return {
    records: response.data?.records || [],
    totalCount: response.data?.totalCount || 0,
  };
}

// Debounce helper for city autocomplete
function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: ReturnType<typeof setTimeout>;

  return (...args: Parameters<T>) => {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

// Example usage: Find companies on Keizersgracht in Amsterdam
async function main() {
  // Step 1: Look up the city
  const cities = await lookupCities('Amsterdam', 'NL');
  console.log('Matching cities:', cities.map(c => c.cityName));

  const city = cities[0]; // Pick the first match
  if (!city) {
    console.log('City not found');
    return;
  }

  // Step 2: Search by address
  const result = await searchByAddress({
    countryCode: 'NL',
    cityName: city.cityName,
    streetName: 'Keizersgracht',
  });

  console.log(`\nFound ${result.totalCount} companies on Keizersgracht, ${city.cityName}:\n`);

  result.records.forEach((company, i) => {
    console.log(`${i + 1}. ${company['Company Name']}`);
    console.log(`   ${company['Address 1']}`);
    console.log(`   ${company['Postal Code']} ${company['City']}`);
    console.log('');
  });

  // Step 3: Paginate through all results
  if (result.totalCount > 25) {
    const page2 = await searchByAddress({
      countryCode: 'NL',
      cityName: city.cityName,
      streetName: 'Keizersgracht',
      page: 2,
    });
    console.log(`Page 2: ${page2.records.length} more companies`);
  }
}

main();

Example Response

Request: GET /api/company/search?countryCode=NL&cityName=AMSTERDAM&streetName=Keizersgracht&statusCode=0,1

{
  "data": {
    "records": [
      {
        "ID": "123456789",
        "Company Name": "Example B.V.",
        "Address 1": "Keizersgracht 424",
        "Postal Code": "1016 GC",
        "City": "AMSTERDAM",
        "Country": "Netherlands"
      }
    ],
    "totalCount": 847
  },
  "page": 1,
  "pageSize": 25,
  "totalPages": 34
}

Best Practices

City Lookup

  • Debounce the input - Wait 300ms after the user stops typing before calling /api/cities
  • Specify the country - Use the countries parameter to narrow city results to the relevant country
  • Use exact city names - Select from the autocomplete results to ensure exact matches in the company search

Address Filtering

  • Combine filters gradually - Start with just a city, then add street or postal code to narrow results
  • Street names use partial matching - You don't need the full street name; "Keizers" will match "Keizersgracht"
  • Postal codes use exact matching - Ensure the format matches the country's postal code format

Pagination

  • Use reasonable page sizes - 10-25 results per page works well for most UIs
  • Show total count - Display the total number of matching companies so users know the scope
  • Add rate limiting for bulk exports - Add delays between pages when exporting large result sets

Was this page helpful?