# Búsqueda

> Busque en la base de datos B2B global de graph8 contactos y empresas con filtros avanzados

Source: https://docs.graph8.com/es/developers/search/

> **Tip: ¿Utiliza el SDK o la CLI?**
> El [SDK de JavaScript](https://docs.graph8.com/developers/sdk/#enrichment) expone la búsqueda como `g8.enrich.search(filters)`. La [CLI](https://docs.graph8.com/developers/cli/#g8-find-contacts) admite `g8 find-contacts --filters '...'` y `g8 build-list`.

> **Note: Gratuito en Platform, medido en PAYG**
> Los endpoints de búsqueda están **incluidos sin costo en el plan Platform de $499 dentro de un límite de 5 rps**: consultan el índice propio de graph8 y no generan costos de terceros. En **PAYG** cuestan **1 crédito por registro** devuelto o guardado. Consulte [Precios](https://docs.graph8.com/developers/pricing/) para ver el mapa completo de paquetes.

Los endpoints de búsqueda consultan el **índice de datos abiertos** de graph8: una base de datos B2B global con millones de contactos y empresas agregados a partir de múltiples proveedores de datos. Úselo para descubrir nuevos prospectos que coincidan con su perfil de cliente ideal (ICP) y guardarlos en su espacio de trabajo.

Esto se diferencia de los endpoints [`/contacts`](https://docs.graph8.com/developers/contacts/) y [`/companies`](https://docs.graph8.com/developers/companies/), que solo devuelven datos que usted ya guardó: sus datos propios del CRM.

> **Tip: ¿Qué endpoint debería usar?**
> - **Quiero encontrar NUEVOS contactos o empresas que aún no tengo** → Use Búsqueda (esta página)
> - **Quiero consultar contactos o empresas que ya guardé** → Use [Contacts](https://docs.graph8.com/developers/contacts/) o [Companies](https://docs.graph8.com/developers/companies/) (gratuito, sin créditos)
> - **Conozco el email o LinkedIn de una persona específica y quiero su perfil** → Use [Enrichment Lookup](https://docs.graph8.com/developers/enrichment/) (consulta de registro único)

### Qué puede buscar

- **Contactos**: filtre por título de trabajo, antigüedad, departamento, habilidades, ubicación, atributos de empresa y más (~28 campos filtrables)
- **Empresas**: filtre por industria, número de empleados, ingresos, geografía, año de fundación, presencia en LinkedIn y más (~15 campos filtrables)

### Cómo se conecta con sus datos

Los resultados de búsqueda provienen del índice de datos abiertos y son de **solo lectura**. Para trabajar con ellos en sus flujos de trabajo:

1. **Buscar**: encuentre contactos o empresas que coincidan con sus criterios
2. **Guardar en lista**: use `/search/contacts/save` o `/search/companies/save` para copiar los registros coincidentes en su espacio de trabajo
3. **Gestionar**: una vez guardados, aparecen en [`/contacts`](https://docs.graph8.com/developers/contacts/) y [`/companies`](https://docs.graph8.com/developers/companies/) como datos propios

> **Note:**
> Los precios dependen de su plan. Consulte la sección de [costos de créditos](#credit-costs) más abajo.

---

## Costos de créditos

| Operación | PAYG | Platform |
|-----------|------|----------|
| Búsqueda de contactos | 1 crédito por registro devuelto | **Incluido gratis** (dentro de 5 rps) |
| Búsqueda de empresas | 1 crédito por registro devuelto | **Incluido gratis** (dentro de 5 rps) |
| Guardar en lista | 1 crédito por registro guardado | **Incluido gratis** (dentro de 5 rps) |

En **PAYG**, una búsqueda que devuelve 25 contactos cuesta 25 créditos. Una búsqueda que devuelve 0 resultados no tiene costo.

En **Platform**, la búsqueda forma parte del paquete ilimitado del índice de graph8; el único límite es el [tope de velocidad de 5 rps](https://docs.graph8.com/developers/rate-limits/).

> **Tip: Valide antes de escalar en PAYG**
> En PAYG, use un `limit` pequeño (p. ej., 5) para previsualizar resultados y validar sus filtros antes de ejecutar una consulta a gran escala. Solo paga por los registros efectivamente devueltos.

---

## Operadores de filtro

Todos los endpoints de búsqueda aceptan un array `filters` en el cuerpo de la solicitud. Cada filtro tiene un `field`, `operator` y `value`.

| Operador | Descripción | Valor de ejemplo |
|----------|-------------|-----------------|
| `any_of` | Coincidencia exacta: el campo coincide con cualquier valor de la lista | `["CEO", "CTO"]` |
| `contains` | Coincidencia difusa o por subcadena | `["sales"]` |
| `all_of` | El campo debe contener TODOS los valores | `["python", "javascript"]` |
| `none_of` | El campo NO debe coincidir con ningún valor | `["intern", "student"]` |
| `is_empty` | El campo no tiene valor | `[]` |
| `is_not_empty` | El campo tiene un valor | `[]` |
| `between` | Rango numérico (inclusivo) | `[2015, 2025]` |
| `exists` | El campo existe en el registro | `[]` |

---

## Búsqueda de contactos

`POST /search/contacts`

Busca en el índice de datos abiertos los contactos que coincidan con los filtros indicados. Devuelve resultados paginados con hasta 100 resultados por página.

### Cuerpo de la solicitud

| Campo | Tipo | Requerido | Descripción |
|-------|------|-----------|-------------|
| `filters` | array | No | Condiciones de filtro (lógica AND). Consulte [operadores de filtro](#filter-operators) |
| `page` | integer | No | Número de página, indexado desde 1 (predeterminado: 1, máx.: 100) |
| `limit` | integer | No | Resultados por página (predeterminado: 25, máx.: 100) |

> **Note:**
> La paginación está limitada a 10,000 resultados en total (`page × limit ≤ 10,000`). Para conjuntos de resultados más grandes, use el endpoint [guardar en lista](#save-contacts-to-list).

### Campos de contacto filtrables

| Campo | Descripción |
|-------|-------------|
| `first_name` | Nombre |
| `last_name` | Apellido |
| `work_email` | Dirección de email laboral |
| `personal_emails` | Direcciones de email personal |
| `direct_phone` | Número de teléfono directo |
| `mobile_phone` | Número de teléfono móvil |
| `job_title` | Título de trabajo |
| `job_department` | Departamento |
| `seniority_level` | Nivel de antigüedad (p. ej., "VP", "Director", "Manager") |
| `role` | Rol |
| `linkedin_url` | URL de perfil de LinkedIn |
| `gender` | Género |
| `skills` | Habilidades |
| `education_degree` | Título académico |
| `education_field` | Campo de estudio |
| `education_university_name` | Nombre de la universidad |
| `city` | Ciudad |
| `state` | Estado o provincia |
| `country` | País |
| `confidence_score` | Puntuación de confianza del dato |
| `company_name` | Nombre de la empresa |
| `company_domain` | Dominio de la empresa |
| `company_industry` | Industria de la empresa |
| `company_employee_count` | Número de empleados de la empresa |
| `company_country` | País de la empresa |
| `company_state` | Estado de la empresa |
| `company_city` | Ciudad de la empresa |
| `company_revenue` | Ingresos de la empresa |
| `company_founded_year` | Año de fundación de la empresa |

### Ejemplo

**cURL**

```bash
curl -X POST "https://be.graph8.com/api/v1/search/contacts" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      {"field": "job_title", "operator": "any_of", "value": ["CEO", "CTO", "VP Engineering"]},
      {"field": "company_industry", "operator": "contains", "value": ["Technology"]},
      {"field": "company_employee_count", "operator": "between", "value": [50, 500]}
    ],
    "page": 1,
    "limit": 25
  }'
```

**Python**

```python
response = requests.post(
    f"{BASE_URL}/search/contacts",
    headers=HEADERS,
    json={
        "filters": [
            {"field": "job_title", "operator": "any_of", "value": ["CEO", "CTO", "VP Engineering"]},
            {"field": "company_industry", "operator": "contains", "value": ["Technology"]},
            {"field": "company_employee_count", "operator": "between", "value": [50, 500]}
        ],
        "page": 1,
        "limit": 25
    }
)
```

**TypeScript**

```typescript
const response = await fetch(`${BASE_URL}/search/contacts`, {
  method: "POST",
  headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    filters: [
      { field: "job_title", operator: "any_of", value: ["CEO", "CTO", "VP Engineering"] },
      { field: "company_industry", operator: "contains", value: ["Technology"] },
      { field: "company_employee_count", operator: "between", value: [50, 500] }
    ],
    page: 1,
    limit: 25
  }),
});
```

### Respuesta

```json
{
  "data": [
    {
      "first_name": "Jane",
      "last_name": "Doe",
      "middle_name": null,
      "work_email": "jane@acme.com",
      "personal_emails": null,
      "direct_phone": "+1-555-0100",
      "mobile_phone": null,
      "job_title": "CEO",
      "job_department": "Executive",
      "seniority_level": "C-Suite",
      "role": "Chief Executive Officer",
      "linkedin_url": "https://linkedin.com/in/janedoe",
      "linkedin_headline": "CEO at Acme Inc",
      "city": "San Francisco",
      "state": "California",
      "country": "United States",
      "company_name": "Acme Inc",
      "company_domain": "acme.com",
      "company_industry": "Technology",
      "company_employee_count": "200",
      "company_country": "United States",
      "confidence_score": 95
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 25,
    "total": 142,
    "has_next": true
  }
}
```

---

## Búsqueda de empresas

`POST /search/companies`

Busca en el índice de datos abiertos las empresas que coincidan con los filtros indicados.

### Cuerpo de la solicitud

Misma estructura que la búsqueda de contactos. Consulte el [cuerpo de la solicitud](#request-body) anterior.

### Campos de empresa filtrables

| Campo | Descripción |
|-------|-------------|
| `name` | Nombre de la empresa |
| `domain` | Dominio de la empresa |
| `website` | URL del sitio web |
| `description` | Descripción de la empresa |
| `industry` | Industria |
| `industry_group` | Grupo de industria |
| `employee_count` | Número de empleados |
| `revenue` | Ingresos anuales |
| `founded_year` | Año de fundación |
| `country` | País |
| `state` | Estado o provincia |
| `city` | Ciudad |
| `phone` | Número de teléfono |
| `linkedin_url` | URL de LinkedIn |
| `linkedin_followers` | Número de seguidores en LinkedIn |

### Ejemplo

**cURL**

```bash
curl -X POST "https://be.graph8.com/api/v1/search/companies" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      {"field": "industry", "operator": "contains", "value": ["Banking"]},
      {"field": "employee_count", "operator": "between", "value": [100, 1000]},
      {"field": "country", "operator": "any_of", "value": ["United States"]}
    ],
    "page": 1,
    "limit": 50
  }'
```

**Python**

```python
response = requests.post(
    f"{BASE_URL}/search/companies",
    headers=HEADERS,
    json={
        "filters": [
            {"field": "industry", "operator": "contains", "value": ["Banking"]},
            {"field": "employee_count", "operator": "between", "value": [100, 1000]},
            {"field": "country", "operator": "any_of", "value": ["United States"]}
        ],
        "page": 1,
        "limit": 50
    }
)
```

**TypeScript**

```typescript
const response = await fetch(`${BASE_URL}/search/companies`, {
  method: "POST",
  headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    filters: [
      { field: "industry", operator: "contains", value: ["Banking"] },
      { field: "employee_count", operator: "between", value: [100, 1000] },
      { field: "country", operator: "any_of", value: ["United States"] }
    ],
    page: 1,
    limit: 50
  }),
});
```

### Respuesta

```json
{
  "data": [
    {
      "name": "First National Bank",
      "domain": "fnb.com",
      "website": "https://www.fnb.com",
      "description": "Regional banking institution...",
      "industry": "Banking",
      "industry_group": "Financial Services",
      "employee_count": "450",
      "revenue": "$100M-$500M",
      "founded_year": 1987,
      "phone": "+1-555-0200",
      "address": "100 Main St",
      "city": "Pittsburgh",
      "state": "Pennsylvania",
      "country": "United States",
      "zip": 15222,
      "linkedin_url": "https://linkedin.com/company/fnb",
      "linkedin_followers": "12500",
      "facebook_url": "https://facebook.com/fnb",
      "twitter_url": "https://twitter.com/fnb",
      "crunchbase_url": null,
      "logo_url": "https://logo.clearbit.com/fnb.com"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 89,
    "has_next": true
  }
}
```

---

## Guardar contactos en lista

`POST /search/contacts/save`

Busca contactos y guarda los resultados coincidentes en una nueva lista dentro de su organización. Los resultados se guardan de forma asíncrona. Devuelve `202 Accepted`.

### Cuerpo de la solicitud

| Campo | Tipo | Requerido | Descripción |
|-------|------|-----------|-------------|
| `filters` | array | No | Condiciones de filtro (lógica AND) |
| `list_title` | string | Sí | Título de la nueva lista |
| `max_results` | integer | No | Máximo de resultados a guardar (predeterminado: 1,000, máx.: 10,000) |

### Ejemplo

**cURL**

```bash
curl -X POST "https://be.graph8.com/api/v1/search/contacts/save" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      {"field": "job_title", "operator": "any_of", "value": ["VP Sales", "Head of Sales"]},
      {"field": "company_industry", "operator": "contains", "value": ["SaaS"]}
    ],
    "list_title": "Sales Leaders in SaaS",
    "max_results": 5000
  }'
```

**Python**

```python
response = requests.post(
    f"{BASE_URL}/search/contacts/save",
    headers=HEADERS,
    json={
        "filters": [
            {"field": "job_title", "operator": "any_of", "value": ["VP Sales", "Head of Sales"]},
            {"field": "company_industry", "operator": "contains", "value": ["SaaS"]}
        ],
        "list_title": "Sales Leaders in SaaS",
        "max_results": 5000
    }
)
list_id = response.json()["data"]["list_id"]
```

**TypeScript**

```typescript
const response = await fetch(`${BASE_URL}/search/contacts/save`, {
  method: "POST",
  headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    filters: [
      { field: "job_title", operator: "any_of", value: ["VP Sales", "Head of Sales"] },
      { field: "company_industry", operator: "contains", value: ["SaaS"] }
    ],
    list_title: "Sales Leaders in SaaS",
    max_results: 5000
  }),
});
const listId = (await response.json()).data.list_id;
```

### Respuesta

```json
{
  "data": {
    "list_id": 42,
    "list_title": "Sales Leaders in SaaS",
    "estimated_total": 3200,
    "status": "processing"
  }
}
```

> **Tip: ¿Qué sucede a continuación?**
> Guardar mueve los contactos desde el índice de datos abiertos de graph8 a su espacio de trabajo. Una vez completado el procesamiento, los contactos guardados se convierten en **sus datos**: puede encontrarlos a través de [`GET /contacts`](https://docs.graph8.com/developers/contacts/) con el filtro `list_id`, gestionar la pertenencia a listas a través de [`/lists`](https://docs.graph8.com/developers/lists/) y enriquecerlos a través de [`/enrichment`](https://docs.graph8.com/developers/enrichment/).

---

## Guardar empresas en lista

`POST /search/companies/save`

Busca empresas y guarda los resultados coincidentes en una nueva lista. Devuelve `202 Accepted`.

### Cuerpo de la solicitud

Misma estructura que [guardar contactos en lista](#save-contacts-to-list), pero utiliza los campos de filtro de empresa.

### Ejemplo

**cURL**

```bash
curl -X POST "https://be.graph8.com/api/v1/search/companies/save" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      {"field": "industry", "operator": "any_of", "value": ["Financial Services"]},
      {"field": "employee_count", "operator": "between", "value": [500, 5000]}
    ],
    "list_title": "Mid-Market Financial Services",
    "max_results": 2000
  }'
```

**Python**

```python
response = requests.post(
    f"{BASE_URL}/search/companies/save",
    headers=HEADERS,
    json={
        "filters": [
            {"field": "industry", "operator": "any_of", "value": ["Financial Services"]},
            {"field": "employee_count", "operator": "between", "value": [500, 5000]}
        ],
        "list_title": "Mid-Market Financial Services",
        "max_results": 2000
    }
)
```

**TypeScript**

```typescript
const response = await fetch(`${BASE_URL}/search/companies/save`, {
  method: "POST",
  headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    filters: [
      { field: "industry", operator: "any_of", value: ["Financial Services"] },
      { field: "employee_count", operator: "between", value: [500, 5000] }
    ],
    list_title: "Mid-Market Financial Services",
    max_results: 2000
  }),
});
```

### Respuesta

```json
{
  "data": {
    "list_id": 43,
    "list_title": "Mid-Market Financial Services",
    "estimated_total": 890,
    "status": "processing"
  }
}
```

> **Tip: ¿Qué sucede a continuación?**
> Las empresas guardadas pasan a formar parte de los datos de su espacio de trabajo y son accesibles a través de [`GET /companies`](https://docs.graph8.com/developers/companies/) y [`/lists`](https://docs.graph8.com/developers/lists/).
