# Mexico Business Directory (DENUE / INEGI) (`hexadatalabs/mexico-business-directory-denue`) Actor

Search Mexico's official business directory DENUE (INEGI) by keyword, state, municipality, SCIAN activity code or geographic radius. Returns 5+ million establishments with activity, employee size, full address and coordinates via INEGI's official API. Pay per result.

- **URL**: https://apify.com/hexadatalabs/mexico-business-directory-denue.md
- **Developed by:** [Hexadata](https://apify.com/hexadatalabs) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 establishment (result)s

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

## Mexico Business Directory (DENUE / INEGI)

Search **DENUE**, the official directory of every economic establishment in Mexico maintained by INEGI (the national statistics institute), and get clean JSON: business name, legal name, SCIAN activity, employee size band, full address, neighborhood, postal code, municipality, state and GPS coordinates. More than **5 million establishments**, from street taco stands to factories.

The Actor uses INEGI's **official public API**, so it is fast, stable and legally clean (INEGI's open-data terms allow commercial reuse with attribution). **Pay per result**: `maxResults` caps the cost.

### What you can use it for

- **B2B prospecting**: every dental clinic in Monterrey, every hotel in Quintana Roo, every manufacturer with 100+ employees in Nuevo León.
- **Geomarketing and site selection**: competitors and complementary businesses within 1 km of a location.
- **Mapping and segmentation**: list and map establishments by activity, employee size and municipality (for bare counts larger than `maxResults`, see Limits).
- **Data enrichment**: match your customer list to official activity codes and coordinates.
- **AI agents**: ask questions about the Mexican business landscape in natural language through MCP (see below).

### Input

Three search modes, chosen automatically from the fields you fill:

| Mode | Fill in | API method |
| --- | --- | --- |
| **Keyword** (default) | `keyword` + optional `state` | BuscarEntidad |
| **Area / activity** | `state` (or `00`) + any of `municipality`, `activityCode`, `employeeStratum`, `nameFilter` (leave `keyword` empty) | BuscarAreaAct(Estr) |
| **Radius** | `latitude` + `longitude` + `radiusMeters` (max 5000) + optional `keyword` | Buscar |

Fields a mode cannot use are not silently dropped: a `keyword` together with area fields, or a `nameFilter` together with coordinates, stops the run with an input error before anything is billed.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `keyword` | string | `todos` | Word(s) in Spanish for the keyword and radius modes. INEGI matches them against business name, legal name, street, neighborhood, activity class, state, municipality and locality; several words are separated by a comma (`consultorios,dentales`). `todos` = everything. Cannot be combined with the area fields. |
| `nameFilter` | string | – | Keep establishments whose trade name contains this text (e.g. `oxxo`). Switches to area mode: `state` `19` + `nameFilter` `oxxo` = every OXXO in Nuevo León. |
| `state` | string | `00` | Two-digit INEGI state code (`09` Ciudad de México, `14` Jalisco, `19` Nuevo León …). `00` = all. |
| `municipality` | string | – | Three-digit municipality code within the state (e.g. `039` Monterrey). Codes: https://www.inegi.org.mx/app/ageeml/ |
| `activityCode` | string | – | SCIAN/NAICS code: 2 digits (sector), 3 (subsector), 4 (rama) or 6 (clase), e.g. `722511` full-service restaurants, `621211` dental offices. |
| `employeeStratum` | string | – | `1` 0–5, `2` 6–10, `3` 11–30, `4` 31–50, `5` 51–100, `6` 101–250, `7` 251+. One band per run. |
| `latitude`, `longitude` | string | – | Center of a radius search in decimal degrees, e.g. `19.4326`, `-99.1332` (a decimal comma also works). Both are required; the run fails instead of silently searching the whole country. |
| `radiusMeters` | integer | `1000` | Up to 5000. Only used with coordinates. |
| `maxResults` | integer | `500` | Total cap. |
| `includeContactFields` | boolean | `false` | Also return the establishment's phone, email and website. Off by default. |
| `inegiToken` | secret | – | Your own free INEGI token. Leave empty to use the Actor's shared token. |

Examples:

```json
{ "keyword": "consultorios,dentales", "state": "19", "maxResults": 1000 }
```

```json
{ "state": "09", "municipality": "015", "activityCode": "7225", "employeeStratum": "3", "maxResults": 2000 }
```

```json
{ "state": "19", "nameFilter": "oxxo", "maxResults": 3000 }
```

```json
{ "keyword": "farmacia", "latitude": "20.6597", "longitude": "-103.3496", "radiusMeters": 1500 }
```

### Output

One item per establishment. This is the sample establishment from INEGI's own API documentation (BuscarEntidad method) as the Actor returns it in keyword mode:

```json
{
    "id": "34185",
    "clee": "01001722514004531",
    "name": "LONCHERÍA LOS CUATES",
    "legalName": null,
    "activity": "Restaurantes con servicio de preparación de tacos y tortas",
    "activityCode": "722514",
    "stateCode": "01",
    "municipalityCode": "001",
    "employeeStratum": "0 a 5 personas",
    "establishmentType": "Fijo",
    "streetType": "CALLE",
    "street": "INEGI",
    "exteriorNumber": "201",
    "interiorNumber": null,
    "neighborhood": "JARDIN DE LAS BUGAMBILIAS",
    "postalCode": "20280",
    "locality": "AGUASCALIENTES",
    "municipality": "Aguascalientes",
    "state": "AGUASCALIENTES",
    "address": "CALLE INEGI No. 201, Col. JARDIN DE LAS BUGAMBILIAS, C.P. 20280, Aguascalientes, AGUASCALIENTES",
    "latitude": 21.85796749,
    "longitude": -102.28485913,
    "shoppingCenter": null,
    "shoppingCenterType": null,
    "localNumber": null,
    "registrationDate": null,
    "mapUrl": "https://www.google.com/maps?q=21.85796749,-102.28485913",
    "source": "INEGI, Directorio Estadístico Nacional de Unidades Económicas (DENUE)",
    "searchKeyword": "tacos",
    "scrapedAt": "2026-10-26T20:11:05.000Z"
}
```

`phone`, `email` and `website` are added only when `includeContactFields` is on. Fields INEGI does not publish for an establishment are `null`. Place names come in INEGI's own casing (locality and state in upper case). `activityCode` (6-digit SCIAN class), `stateCode` and `municipalityCode` are filled in every mode: INEGI returns the class code directly in area mode, and in all modes the CLEE encodes state (2 digits), municipality (3) and class (6), so the Actor derives them from it and you can join results to your own INEGI-coded data. `registrationDate` is only returned by the area/activity mode. `searchKeyword` holds the `keyword` (keyword and radius modes) or the `nameFilter` (area mode).

### Pricing & cost examples

**$2.00 per 1,000 establishments** (pay per event, charged only for items saved to the dataset; duplicates and errors are never billed). `maxResults` is a hard cost cap. Examples: 1,000 establishments ≈ $2.00 · all dental offices in Nuevo León (~3,000) ≈ $6 · a 500-result territory list ≈ $1.00. Apify platform usage is included in the price.

### Use it from an AI agent (MCP)

Every Apify Actor is available as a tool through the [Apify MCP server](https://mcp.apify.com). Add `https://mcp.apify.com/?tools=hexadatalabs/mexico-business-directory-denue` as an MCP server in Claude, Cursor, VS Code or any MCP client (with your Apify token) and ask:

> "How many hotels with 51 to 100 employees are there in Cancún, and where are they?"

The agent calls this Actor with `{"state":"23","municipality":"005","activityCode":"7211","employeeStratum":"5"}` and reasons over the results. For "more than 50 employees" the agent runs it once per band (`employeeStratum` `5`, `6` and `7`), or once without `employeeStratum` and filters the `employeeStratum` field itself.

From code:

```bash
curl -X POST "https://api.apify.com/v2/acts/hexadatalabs~mexico-business-directory-denue/run-sync-get-dataset-items?token=<APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"keyword":"ferreteria","state":"14","maxResults":300}'
```

```python
from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("hexadatalabs/mexico-business-directory-denue").call(run_input={
    "state": "19", "municipality": "039", "activityCode": "3363", "maxResults": 500,
})
for biz in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(biz["name"], biz["activity"], biz["employeeStratum"], biz["address"])
```

### Limits and notes

- Data is INEGI's DENUE snapshot (updated by INEGI about twice a year). It is a census-based directory, not a live business listing.
- Keyword matching is done by INEGI in Spanish. Per INEGI's API documentation the words are searched in the business name, legal name, street, neighborhood, activity class, state, municipality and locality, so a keyword such as `hidalgo` also returns businesses on a street or in a municipality with that name. Several words must be separated by a comma (`consultorios,dentales`); INEGI's vocabulary works best (`restaurantes`, `dentales`, `talleres,mecanicos`).
- Radius searches return everything within the radius in one call (no paging); area and keyword searches page 100 records at a time.
- Nation-wide `todos` searches without an activity code are huge; use `maxResults` or narrow by state.
- A count is only exact up to `maxResults`; larger result sets are truncated at that cap, so for market sizing set `maxResults` above the expected total or narrow the area.
- The Actor's shared INEGI token is used by every customer of this Actor and INEGI rate-limits it; for large or scheduled jobs request your own free token and pass it in `inegiToken`.
- Runs can be aborted and resurrected: progress (page offset and the ids already saved) is persisted, so a resurrected or migrated run continues where it stopped without pushing duplicates.

### Legal notice and attribution

Data comes from INEGI's DENUE through its official API, under INEGI's [terms of free use](https://www.inegi.org.mx/inegi/terminos.html), which permit copying, extraction, adaptation and commercial use with attribution. When you publish or redistribute the data, cite it as **"Fuente: INEGI, Directorio Estadístico Nacional de Unidades Económicas (DENUE)"** and do not imply INEGI endorses your product. Phone, email and website are business contact details published by INEGI; they are omitted unless you explicitly request them, and you remain responsible for using them lawfully (e.g. Mexico's LFPDPPP for sole proprietors).

### Changelog

- **0.1** (2026-10-27) — First public release.

### Support

Found a problem or need another field? Open an issue in the **Issues** tab of this Actor; we answer within 24 hours and ship confirmed fixes within 48 hours.

***

#### En español

Consulta el DENUE del INEGI (más de 5 millones de negocios en México) por palabra clave, estado, municipio, código SCIAN o radio geográfico, usando la API oficial. Devuelve nombre, razón social, actividad, tamaño por empleados, dirección completa y coordenadas. Se cobra por resultado; usa `maxResults` para limitar el costo. Varias palabras se separan con coma (`consultorios,dentales`). Teléfono, correo y sitio web solo se incluyen si activas `includeContactFields`. Cita siempre "Fuente: INEGI, DENUE".

# Actor input Schema

## `keyword` (type: `string`):

Word(s) to search in Spanish, used by the keyword and radius modes. INEGI matches them against the business name, legal name, street, neighborhood, activity class, state, municipality and locality (for example "dentista", "restaurantes", "ferreteria", "hotel", "farmacia"); separate several words with a comma ("consultorios,dentales"). Use "todos" for everything. Cannot be combined with municipality, activityCode, employeeStratum or nameFilter (area mode): leave it empty or "todos" there and use nameFilter or activityCode instead.

## `nameFilter` (type: `string`):

Substring of the establishment's trade name, e.g. "oxxo". Setting it switches to area mode (state + optional municipality / activityCode / employeeStratum), so "state" 19 + nameFilter "oxxo" returns every OXXO in Nuevo León. Cannot be combined with keyword or with a radius search.

## `state` (type: `string`):

Two-digit INEGI state code. 00 = whole country.

## `municipality` (type: `string`):

Three-digit INEGI municipality code inside the selected state (for example 039 = Monterrey in Nuevo León 19, 015 = Cuauhtémoc in Ciudad de México 09). Requires a state. Find codes at https://www.inegi.org.mx/app/ageeml/

## `activityCode` (type: `string`):

North American Industry Classification (SCIAN/NAICS) code with 2 to 6 digits: 2 = sector (e.g. 72 food services), 3 = subsector, 4 = industry group (rama), 6 = class (e.g. 722511 full-service restaurants). Narrows the search to that activity.

## `latitude` (type: `string`):

Center of a radius search, e.g. 19.4326 (decimal degrees; a decimal comma is accepted). Set latitude, longitude and radiusMeters to search around a point instead of by area; both coordinates are required.

## `longitude` (type: `string`):

e.g. -99.1332 (decimal degrees, negative for Mexico). Required together with latitude.

## `radiusMeters` (type: `integer`):

Radius around the point for the radius search (only used when latitude and longitude are set). INEGI allows up to 5000 m.

## `employeeStratum` (type: `string`):

Filter by number of employees (INEGI stratum). Only applies to area searches (state / municipality / activity code).

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

Stop after this many establishments. You are charged per result, so this caps the cost.

## `includeContactFields` (type: `boolean`):

DENUE publishes the establishment's phone, email and website. They are omitted by default; turn this on only if you have a lawful basis to use business contact data.

## `inegiToken` (type: `string`):

Your own free DENUE API token from https://www.inegi.org.mx/app/desarrolladores/generatoken/Usuarios/token_Verify . Leave empty to use the Actor's shared token, which all users of this Actor share and INEGI rate-limits; for large or scheduled jobs request your own.

## Actor input object example

```json
{
  "keyword": "dentista",
  "state": "00",
  "radiusMeters": 1000,
  "maxResults": 500,
  "includeContactFields": false
}
```

# Actor output Schema

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

No description

# 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 = {
    "keyword": "dentista"
};

// Run the Actor and wait for it to finish
const run = await client.actor("hexadatalabs/mexico-business-directory-denue").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 = { "keyword": "dentista" }

# Run the Actor and wait for it to finish
run = client.actor("hexadatalabs/mexico-business-directory-denue").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 '{
  "keyword": "dentista"
}' |
apify call hexadatalabs/mexico-business-directory-denue --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hexadatalabs/mexico-business-directory-denue"
        }
    }
}
```

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/x7y83FCL5LIlG7sIH/builds/MxDxf4vPdwxpAyZbo/openapi.json
