# Business License Scraper: New Business Leads from US Cities (`nightwave-owner/us-business-licenses`) Actor

Returns new business licenses and registered business locations from Seattle, San Francisco and Los Angeles open data: business name, DBA, industry and NAICS code, address, ZIP, start date and status. Filter by city, date, industry and name.

- **URL**: https://apify.com/nightwave-owner/us-business-licenses.md
- **Developed by:** [Viktor Wiberg](https://apify.com/nightwave-owner) (community)
- **Categories:** Lead generation, Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$3.00 / 1,000 business licenses

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Business License Scraper: New Business Leads from US Cities

A business license scraper for B2B leads. It collects new business licenses and newly registered business locations from the official open data portals of Seattle, San Francisco and Los Angeles, one row per record in one schema: city, license or account number, business name, DBA name, license type, business activity, NAICS code, street address, ZIP, start date, status and a link to the record in the city's API.

Use it to find businesses that just opened or registered in a city (restaurants, shops, contractors, offices), to feed a CRM with fresh local leads every morning, or to count new businesses per industry and ZIP for a market report, instead of downloading each city's file by hand.

### What is covered

| City | Portal | Dataset | License |
|---|---|---|---|
| Seattle, WA | data.seattle.gov | [Active Business License Tax Certificate](https://data.seattle.gov/d/wnbq-64tb) (`wnbq-64tb`) | Public Domain |
| San Francisco, CA | data.sf.gov | [Registered Business Locations - San Francisco](https://data.sf.gov/d/g8m3-pdis) (`g8m3-pdis`) | Open Data Commons PDDL |
| Los Angeles, CA | data.lacity.org | [Listing of Active Businesses](https://data.lacity.org/d/6rrh-rzua) (`6rrh-rzua`) | CC0 1.0 (Public Domain Dedication) |

The actor reads the datasets live through the Socrata SODA API, so a run returns what the portal has at that moment. Seattle and San Francisco update daily. Los Angeles states a monthly update interval in its metadata.

- Filters: city, start date range, license type or industry words, NAICS code prefixes, text in the business name, active businesses only.
- Private persons are left out by default (`excludeIndividuals`): sole proprietors and records that look like a person at a home address. See "Private persons" below.
- Newest first across all selected cities.
- With no input the actor returns the 50 newest active business records from the last 30 days across all three cities, without private persons.

### Example from a real run

This is a run on the Apify platform on 8 October 2026 with empty input (run `3qX764YkYSpR2iKNV`): the 50 newest active records from the last 30 days across all three cities, with `excludeIndividuals` at its default `true`. The log showed 32 San Francisco rows and 44 Los Angeles rows left out as likely private persons; Seattle's sole proprietors were filtered out on the portal. Three of the 50 rows:

Input:

```json
{}
```

Output (excerpt):

```json
[
  {
    "city": "Los Angeles",
    "state": "CA",
    "licenseNumber": "0003567811-0001-2",
    "businessName": "NOBLE PACK LOGISTICS LLC",
    "dbaName": null,
    "entityType": null,
    "licenseType": "Office of Finance business registration",
    "businessActivity": "Office administrative services",
    "naicsCode": "561110",
    "addressLine": "4716 S GRAMERCY PLACE, Los Angeles",
    "zip": "90062",
    "latitude": null,
    "longitude": null,
    "issuedAt": "2026-10-07",
    "expiresAt": null,
    "status": "Active",
    "isLikelyIndividual": false,
    "sourceUrl": "https://data.lacity.org/resource/6rrh-rzua.json?location_account=0003567811-0001-2",
    "sourceDataset": "https://data.lacity.org/d/6rrh-rzua",
    "license": "Creative Commons 1.0 Universal (Public Domain Dedication)"
  },
  {
    "city": "San Francisco",
    "state": "CA",
    "licenseNumber": "1189473",
    "businessName": "Mission 19 Taqueria LLC",
    "dbaName": "Sf Vibe Creamery",
    "entityType": null,
    "licenseType": null,
    "businessActivity": null,
    "naicsCode": "722515",
    "addressLine": "275 Jefferson St, San Francisco",
    "zip": "94133",
    "latitude": 37.807992,
    "longitude": -122.4168525,
    "issuedAt": "2026-10-07",
    "expiresAt": null,
    "status": "Active",
    "isLikelyIndividual": false,
    "sourceUrl": "https://data.sf.gov/resource/g8m3-pdis.json?uniqueid=1434493-10-261-1189473",
    "sourceDataset": "https://data.sf.gov/d/g8m3-pdis",
    "license": "Open Data Commons Public Domain Dedication and License (PDDL)"
  }
]
```

A Seattle row from the same run shows the ownership type that Seattle adds:

```json
{
  "city": "Seattle",
  "state": "WA",
  "licenseNumber": "0008958310813717",
  "businessName": "ELEVATE WINDOWS LLC",
  "dbaName": "ELEVATE WINDOWS LLC",
  "entityType": "LLC - Multi Member",
  "licenseType": "Business License Tax Certificate",
  "businessActivity": "Glass and Glazing Contractors",
  "naicsCode": "238150",
  "addressLine": "11900 NE 1ST ST STE 300, Bellevue",
  "zip": "98005",
  "latitude": null,
  "longitude": null,
  "issuedAt": "2026-10-06",
  "expiresAt": null,
  "status": "Active",
  "isLikelyIndividual": false,
  "sourceUrl": "https://data.seattle.gov/resource/wnbq-64tb.json?city_account_number=0008958310813717",
  "sourceDataset": "https://data.seattle.gov/d/wnbq-64tb",
  "license": "Public Domain"
}
```

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `cities` | array | all three | `seattle`, `san-francisco`, `los-angeles`. Names such as "San Francisco", "SF" or "LA" also work. |
| `licenseTypes` | array | all | Words that must appear in `licenseType` or `businessActivity`, or NAICS code prefixes, any of them. For example `["restaurant"]`, `["7225"]` or `["salon", "8121"]`. |
| `businessNameContains` | string | none | Text that must appear in the business name or DBA name, case insensitive. |
| `issuedFrom` | date | 30 days ago | Records that started on or after this date, `YYYY-MM-DD`. |
| `issuedTo` | date | today | Records that started on or before this date. Future start dates, which some portals hold, are left out by default. |
| `activeOnly` | boolean | true | Leave out locations that the city lists as closed or ended. |
| `maxResults` | integer | 50 | Rows in total, 1 to 10 000. |
| `onlyNew` | boolean | false | Only records that earlier runs with the same input did not deliver. |
| `excludeIndividuals` | boolean | true | Leave out sole proprietors and records that look like a private person at a home address. Set `false` only if you have a lawful basis to process personal data. |

### Output

| Field | Description |
|---|---|
| `city`, `state` | The city whose portal the row comes from, and its two letter state code. |
| `licenseNumber` | Seattle: city account number. San Francisco: business account (certificate) number, shared by all locations of one business. Los Angeles: location account number. |
| `businessName` | Registered or legal business name as the city publishes it. For sole proprietors this is the owner's name, which is why they are left out by default. |
| `dbaName` | Trade name or "doing business as" name, `null` when the city has none. |
| `entityType` | Seattle only: ownership type such as Corporation, LLC - Single Member or Sole proprietorship. |
| `licenseType` | Seattle: Business License Tax Certificate. San Francisco: the city's license code description where one exists (most rows have none). Los Angeles: Office of Finance business registration. |
| `businessActivity` | Industry in words (NAICS description) for Seattle and Los Angeles. San Francisco publishes only the code. |
| `naicsCode` | NAICS industry code as reported by the business. Los Angeles uses 2007 NAICS codes. |
| `addressLine`, `zip` | Business location street address and locality, and five digit ZIP. |
| `latitude`, `longitude` | Coordinates where the city publishes them (San Francisco, part of Los Angeles), otherwise `null`. Seattle publishes none. |
| `issuedAt` | Start date, `YYYY-MM-DD`: license start date in Seattle, location start date in San Francisco and Los Angeles. |
| `expiresAt` | End date of the location or DBA when the city has recorded one (only with `activeOnly: false`), otherwise `null`. |
| `status` | `Active` or `Closed`. |
| `isLikelyIndividual` | `true` when the record looks like a private person: in Seattle an ownership type of Sole proprietorship, General Partnership, Trust or Other, in San Francisco and Los Angeles a person's name or a home address (see "Private persons"). With `excludeIndividuals: true` (the default) every delivered row has `false`. |
| `sourceUrl` | SODA API link that returns exactly this record from the portal. |
| `sourceDataset`, `license` | The dataset the row comes from and its license. |

The schema leaves out personal contact data on purpose: phone numbers, mailing addresses, e-mail, separate owner fields and state tax ids are never requested from the portals.

### Private persons

The cities register sole proprietors under the owner's own name, often at a home address. That is personal data, so by default (`excludeIndividuals: true`) the actor leaves out every record that looks like a private person:

- **Seattle:** the city's own `ownership_type` field. Sole proprietorship, General Partnership, Trust and Other are filtered out on the portal before any row is downloaded.
- **San Francisco and Los Angeles:** the portals have no ownership type, so a rule decides. A record is left out when the owner part of the business name (the text before "DBA" or a colon) has no company word (LLC, Inc, Corp, Co, Ltd, LP, LLP, PC, PLLC, Trust, Group, Services, Restaurant, Cafe, Bar, Salon and similar) and one of its names is 2-4 words without digits. Names are split on "&", commas, slashes and the word "and", and a name with an initial (a single letter such as the A in "Scott A M") next to a longer word counts as a person at any length. A record is also left out when the address has an apartment or unit number (APT, UNIT, #12) and no suite or floor.

Every row carries `isLikelyIndividual`. Set `excludeIndividuals` to `false` only if you have a lawful basis to process personal data; the records that look like private persons are then delivered with `isLikelyIndividual: true`.

### Monitoring and scheduling

Set `onlyNew` to `true` to use the actor as a daily new business feed. The actor then remembers which records it has delivered for the same input, in a named key-value store in your Apify account (`nightwave-state-us-business-licenses`, one record per input). Each run returns and charges only records that earlier runs did not deliver. The first run returns everything in the selection. A run without news finishes successfully with 0 rows.

`onlyNew` and `maxResults` are not part of the remembered input, so you can change them without starting over. Changing any other field starts a fresh state. Leave `issuedFrom` empty in a schedule: it then always looks 30 days back, and records you already have are skipped. That also catches records that a city adds to its file a few days late.

Example: every morning at 07:00, new restaurants and cafes in Seattle and Los Angeles. In Apify Console, open **Schedules**, create a schedule with the cron expression `0 7 * * *` and add this actor with the input below.

```json
{
  "cities": ["seattle", "los-angeles"],
  "licenseTypes": ["7225"],
  "onlyNew": true,
  "maxResults": 500
}
```

The same schedule through the Apify API:

```sh
curl -X POST "https://api.apify.com/v2/schedules?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"name": "daily-new-businesses", "cronExpression": "0 7 * * *", "timezone": "America/Los_Angeles", "isEnabled": true, "isExclusive": true,
       "actions": [{"type": "RUN_ACTOR", "actorId": "nightwave-owner~us-business-licenses",
                    "runInput": {"contentType": "application/json; charset=utf-8", "body": "<the input above as a JSON string>"}}]}'
```

Connect a webhook or an integration (Slack, e-mail, Google Sheets, HubSpot) to the actor in Apify Console if you want the new rows sent somewhere when the run finishes.

### Limitations

- The three cities publish different things. Seattle lists businesses that hold a Seattle business license tax certificate, San Francisco lists registered business locations, Los Angeles lists businesses registered with the Office of Finance. All three include businesses whose address is outside the city (for example a Bellevue company with a Seattle license), so filter on `zip` or `addressLine` if you need only local addresses.
- The start date is the date the city recorded, which can be before or after the actual opening. Some records carry future start dates. They are left out unless you set `issuedTo` in the future.
- Seattle's dataset lists only active licenses. The Los Angeles dataset is named "Listing of Active Businesses", but the actor still applies `activeOnly` there (rows with a `location_end_date` are left out, and with `activeOnly: false` they are delivered with status `Closed`). On 8 October 2026 no Los Angeles row had an end date, so in practice `activeOnly: false` changes the result only for San Francisco.
- `excludeIndividuals` works on Seattle's own ownership type field, but in San Francisco and Los Angeles it is a rule based on the name and address. The rule also removes some real companies whose registered name is a person's name or a short name without a company word (for example a studio named after its owner), and it can miss a sole proprietor with a company-like trade name at a business address.
- Industry codes are self reported by the business and are sometimes broad (for example `310000`).
- Chicago and New York City are not included. Chicago's business license dataset is published under the City's terms of use (with an indemnity clause) rather than a public domain license, and the New York City dataset states no license in its metadata, so they are left out until that changes.
- A city that does not answer is logged as a warning and the run continues with the other cities. The run fails only if every selected portal fails.
- Each city is read with at most 20 000 rows per run. Narrow the date range if you need more history from one city.

### Use cases

- **Sales teams and agencies:** new restaurants, salons, offices or contractors in a city, every morning, for outreach through your own channels.
- **Suppliers and service companies:** POS, payroll, insurance, signage, cleaning and food suppliers looking for businesses that just opened.
- **Market research:** count new businesses per NAICS code and ZIP to see which industries and neighbourhoods grow.
- **Local news and economic development:** track openings by industry over time.

### FAQ

**Is this the official data?** Yes. Every row comes straight from the city's own Socrata portal, and `sourceUrl` returns the same record from the portal's API.

**Do I get owner names, phone numbers or e-mail?** No. The actor returns business data only, and records of sole proprietors and other private persons are left out by default (see "Private persons").

**Can you add my city?** Only cities whose business license dataset is published under a public domain or equivalent open license are added. Write to kontakt@nightwave.se with the dataset link.

### Data source and license

All data comes from the Socrata Open Data API (SODA) of each portal listed in the table above. The license of each dataset was read from the portal's own metadata (`/api/views/<id>.json`) on 7 October 2026, and is repeated in the `license` field of every row:

- Seattle: "Public Domain".
- San Francisco: "Open Data Commons Public Domain Dedication and License" (http://opendatacommons.org/licenses/pddl/1.0/).
- Los Angeles: "Creative Commons 1.0 Universal (Public Domain Dedication)" (http://creativecommons.org/publicdomain/zero/1.0/legalcode).

These licenses allow copying, changing and commercial reuse without permission. The cities provide the data as is and make no warranty about its accuracy. This actor is not affiliated with or endorsed by any of the cities.

### Pricing

Pay per result: 0.003 USD per record returned (event `license`), which is 3 USD per 1 000 records. Apify bills platform usage on top as usual. It is small: a test run on 7 October 2026 that returned 1 000 records from all three cities (run `8yQBeRtcySdP2iQaY`) took about 3 seconds and used 0.0052 USD of platform usage. `maxResults` caps how many rows a run returns, so you always know the highest possible cost.

Rows are delivered only after they have been charged. If you set a maximum cost per run (maxTotalChargeUsd), the run stops there and its status message says how many rows were delivered.

### Contact

Built and maintained by Nightwave AB. Questions, bugs and feature requests: kontakt@nightwave.se

### På svenska

Actorn hämtar nya företagstillstånd och nyregistrerade verksamhetsadresser från de öppna dataportalerna i Seattle, San Francisco och Los Angeles, en rad per post i ett gemensamt format: stad, licens- eller kontonummer, företagsnamn, handelsnamn (DBA), licenstyp, bransch, NAICS-kod, adress, postnummer, startdatum, status och en länk till posten i stadens API.

- Källa: varje stads Socrata-portal (SODA API), läst direkt vid körningen. Ingen API-nyckel behövs.
- Licens: bara dataset som enligt portalens egen metadata är public domain (Public Domain, PDDL eller CC0) är med, kontrollerat 7 oktober 2026. Licensen står i fältet `license` på varje rad. Chicago och New York är inte med: Chicagos dataset har stadens användarvillkor i stället för en öppen licens och New Yorks dataset anger ingen licens.
- Inga personuppgifter: telefonnummer, postadresser, e-post, separata ägarfält och skattenummer hämtas aldrig. Enskilda firmor och poster som ser ut som en privatperson på en bostadsadress tas bort som standard (`excludeIndividuals`). I Seattle används stadens eget fält för ägarform, i San Francisco och Los Angeles en regel på namn och adress som också kan ta bort en del riktiga företag. Fältet `isLikelyIndividual` finns på varje rad.
- Filter: stad, datumintervall, ord i licenstyp eller bransch, NAICS-prefix, text i företagsnamnet och bara aktiva verksamheter. Utan input fås de 50 senaste aktiva företagsposterna från de senaste 30 dagarna i alla tre städerna.
- Med `onlyNew: true` levereras bara poster som tidigare körningar med samma input inte har levererat, vilket passar för daglig bevakning (se "Monitoring and scheduling").
- Pris: 0,003 USD per post (3 USD per 1 000) plus Apifys plattformsanvändning.
- Kontakt: kontakt@nightwave.se

# Actor input Schema

## `cities` (type: `array`):

Which cities to read. Leave empty for all three (the default). Example: \["seattle", "los-angeles"].

## `licenseTypes` (type: `array`):

Optional. Words that must appear in the license type or business activity (case insensitive, any of them), or NAICS code prefixes. Example: \["restaurant", "7225"]. Leave empty for all.

## `businessNameContains` (type: `string`):

Optional. Text that must appear in the business name or DBA name (case insensitive). Example: "coffee".

## `issuedFrom` (type: `string`):

Only records whose license or business location started on or after this date, YYYY-MM-DD. Defaults to 30 days ago. Example: 2026-09-01.

## `issuedTo` (type: `string`):

Only records that started on or before this date, YYYY-MM-DD. Defaults to today, so future start dates are left out. Example: 2026-09-30.

## `activeOnly` (type: `boolean`):

Leave out businesses that the city lists as closed or ended. Defaults to true. Example: false to include closed San Francisco locations.

## `maxResults` (type: `integer`):

Maximum number of records in total, newest first across the selected cities, for example 50. 1 to 10 000, defaults to 50.

## `onlyNew` (type: `boolean`):

Return only records that earlier runs with the same input did not deliver, for example true for a daily new business feed. Defaults to false.

## `excludeIndividuals` (type: `boolean`):

Leave out sole proprietors and records that look like a private person at a home address. Set false only if you have a lawful basis to process personal data.

## Actor input object example

```json
{
  "cities": [
    "seattle",
    "los-angeles"
  ],
  "licenseTypes": [
    "restaurant",
    "7225"
  ],
  "businessNameContains": "coffee",
  "issuedFrom": "2026-09-01",
  "issuedTo": "2026-09-30",
  "activeOnly": true,
  "maxResults": 50,
  "onlyNew": true,
  "excludeIndividuals": true
}
```

# Actor output Schema

## `results` (type: `string`):

All business license records produced by the run, as JSON. Open in Apify Console or download via the dataset API.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "activeOnly": true,
    "maxResults": 50,
    "onlyNew": false,
    "excludeIndividuals": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("nightwave-owner/us-business-licenses").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "activeOnly": True,
    "maxResults": 50,
    "onlyNew": False,
    "excludeIndividuals": True,
}

# Run the Actor and wait for it to finish
run = client.actor("nightwave-owner/us-business-licenses").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "activeOnly": true,
  "maxResults": 50,
  "onlyNew": false,
  "excludeIndividuals": true
}' |
apify call nightwave-owner/us-business-licenses --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nightwave-owner/us-business-licenses"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MaHiiQKbd8pVry0mQ/builds/6MOf8ttGALzmwzZwp/openapi.json
