> ## Documentation Index
> Fetch the complete documentation index at: https://docs.firecrawl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Modo JSON - Resultado estructurado

> Extrae datos estructurados de páginas mediante LLM

**Elegir la herramienta adecuada.** El modo JSON (esta página) es la opción adecuada cuando tienes **una URL** y quieres extraer campos de esa única página.

* Para **cualquier caso que vaya más allá de una sola URL** — varias URL, patrones de URL o descubrimiento con agentes — consulta [Agent](/es/features/agent).
* Comparación completa: [Cómo elegir el extractor de datos](/es/developer-guides/usage-guides/choosing-the-data-extractor).

<Note>
  **Cambio en la API v2:** La extracción de esquemas JSON está totalmente soportada en v2, pero el formato de la API ha cambiado. En v2, el esquema se incorpora directamente dentro del objeto de formato como `formats: [{type: "json", schema: {...}}]`. El parámetro `jsonOptions` de v1 ya no existe en v2.
</Note>

<Note>Para errores de validación de esquemas y otros errores de extracción, consulta [Errors](/es/api-reference/errors) — los problemas específicos de extracción suelen mostrarse como respuestas `400` o `422`.</Note>

<div id="scrape-and-extract-structured-data-with-firecrawl">
  ## Rastrea y extrae datos estructurados con Firecrawl
</div>

Firecrawl usa IA para obtener datos estructurados de páginas web en 3 pasos:

1. **Configura el esquema (opcional):**
   Define un esquema JSON (usando el formato de OpenAI) para especificar los datos que necesitas, o simplemente proporciona un `prompt` si no requieres un esquema estricto, junto con la URL de la página.

2. **Haz la solicitud:**
   Envía tu URL y el esquema a nuestro punto de conexión /scrape usando el modo JSON. Mira cómo aquí:
   [Scrape Endpoint Documentation](https://docs.firecrawl.dev/api-reference/endpoint/scrape)

3. **Obtén tus datos:**
   Recibe datos limpios y estructurados que coincidan con tu esquema y que puedas usar de inmediato.

Esto hace que obtener datos web en el formato que necesitas sea rápido y sencillo.

<div id="extract-structured-data">
  ## Extrae datos estructurados
</div>

<div id="json-mode-via-scrape">
  ### Modo JSON con /scrape
</div>

Se utiliza para extraer datos estructurados de páginas rastreadas.

<CodeGroup>
  ```python Python theme={null}
  from firecrawl import Firecrawl
  from pydantic import BaseModel

  app = Firecrawl(
    # No se necesita API key para comenzar — agrega una para obtener límites de tasa más altos:
    # api_key="fc-YOUR-API-KEY",
  )

  class CompanyInfo(BaseModel):
      company_mission: str
      supports_sso: bool
      is_open_source: bool
      is_in_yc: bool

  result = app.scrape(
      'https://firecrawl.dev',
      formats=[{
        "type": "json",
        "schema": CompanyInfo.model_json_schema()
      }],
      only_main_content=False,
      timeout=120000
  )

  print(result)
  ```

  ```js Node theme={null}
  import { Firecrawl } from "firecrawl";
  import { z } from "zod";

  const app = new Firecrawl({
    // No se necesita API key para comenzar — agrega una para límites de tasa más altos:
    // apiKey: "fc-YOUR_API_KEY",
  });

  // Definir esquema para extraer el contenido
  const schema = z.object({
    company_mission: z.string(),
    supports_sso: z.boolean(),
    is_open_source: z.boolean(),
    is_in_yc: z.boolean()
  });

  const result = await app.scrape("https://firecrawl.dev", {
    formats: [{
      type: "json",
      schema: schema
    }],
  });

  console.log(result);
  ```

  ```bash cURL theme={null}
  # No se necesita API key para comenzar — añade -H "Authorization: Bearer YOUR_API_KEY" para límites de tasa más altos:
  curl -X POST https://api.firecrawl.dev/v2/scrape \
      -H 'Content-Type: application/json' \
      -d '{
        "url": "https://firecrawl.dev",
        "formats": [ {
          "type": "json",
          "schema": {
            "type": "object",
            "properties": {
              "company_mission": {
                        "type": "string"
              },
              "supports_sso": {
                        "type": "boolean"
              },
              "is_open_source": {
                        "type": "boolean"
              },
              "is_in_yc": {
                        "type": "boolean"
              }
            },
            "required": [
              "company_mission",
              "supports_sso",
              "is_open_source",
              "is_in_yc"
            ]
          }
        } ]
      }'
  ```
</CodeGroup>

Salida:

```json JSON theme={null}
{
    "success": true,
    "data": {
      "json": {
        "company_mission": "Rastreo y extracción de datos web con IA",
        "supports_sso": true,
        "is_open_source": true,
        "is_in_yc": true
      },
      "metadata": {
        "title": "Firecrawl",
        "description": "Rastreo y extracción de datos web con IA",
        "robots": "seguir, indexar",
        "ogTitle": "Firecrawl",
        "ogDescription": "Rastreo y extracción de datos web con IA",
        "ogUrl": "https://firecrawl.dev/",
        "ogImage": "https://firecrawl.dev/og.png",
        "ogLocaleAlternate": [],
        "ogSiteName": "Firecrawl"
        "sourceURL": "https://firecrawl.dev/"
      },
    }
}
```

<div id="structured-data-without-schema">
  ### Datos estructurados sin esquema
</div>

También puedes extraer sin esquema pasando únicamente un `prompt` al punto de conexión. El LLM elige la estructura de los datos.

<CodeGroup>
  ```python Python theme={null}
  from firecrawl import Firecrawl

  app = Firecrawl(
    # No se necesita API key para comenzar — añade una para obtener límites de tasa más altos:
    # api_key="fc-YOUR-API-KEY",
  )

  result = app.scrape(
      'https://firecrawl.dev',
      formats=[{
        "type": "json",
        "prompt": "Extract the company mission from the page."
      }],
      only_main_content=False,
      timeout=120000
  )

  print(result)
  ```

  ```js Node theme={null}
  import { Firecrawl } from "firecrawl";

  const app = new Firecrawl({
    // No se necesita API key para comenzar — agrega una para obtener límites de tasa más altos:
    // apiKey: "fc-YOUR_API_KEY",
  });

  const result = await app.scrape("https://firecrawl.dev", {
    formats: [{
      type: "json",
      prompt: "Extract the company mission from the page."
    }]
  });

  console.log(result);
  ```

  ```bash cURL theme={null}
  # No se necesita API key para comenzar — añade -H "Authorization: Bearer YOUR_API_KEY" para límites de tasa más altos:
  curl -X POST https://api.firecrawl.dev/v2/scrape \
      -H 'Content-Type: application/json' \
      -d '{
        "url": "https://firecrawl.dev",
        "formats": [{
          "type": "json",
          "prompt": "Extract the company mission from the page."
        }]
      }'
  ```
</CodeGroup>

Salida:

```json JSON theme={null}
{
    "success": true,
    "data": {
      "json": {
        "company_mission": "Rastreo web y extracción de datos impulsados por IA",
      },
      "metadata": {
        "title": "Firecrawl",
        "description": "Rastreo web y extracción de datos impulsados por IA",
        "robots": "seguir, indexar",
        "ogTitle": "Firecrawl",
        "ogDescription": "Rastreo web y extracción de datos impulsados por IA",
        "ogUrl": "https://firecrawl.dev/",
        "ogImage": "https://firecrawl.dev/og.png",
        "ogLocaleAlternate": [],
        "ogSiteName": "Firecrawl",
        "sourceURL": "https://firecrawl.dev/"
      },
    }
}
```

<div id="real-world-example-extracting-company-information">
  ### Ejemplo real: extracción de información de empresas
</div>

A continuación, un ejemplo completo que extrae información estructurada de un sitio web sobre una empresa:

<CodeGroup>
  ```python Python theme={null}
  from firecrawl import Firecrawl
  from pydantic import BaseModel

  app = Firecrawl(
    # No se necesita API key para comenzar — agrega una para obtener límites de tasa más altos:
    # api_key="fc-YOUR-API-KEY",
  )

  class CompanyInfo(BaseModel):
      company_mission: str
      supports_sso: bool
      is_open_source: bool
      is_in_yc: bool

  result = app.scrape(
      'https://firecrawl.dev/',
      formats=[{
          "type": "json",
          "schema": CompanyInfo.model_json_schema()
      }]
  )

  print(result)
  ```

  ```js Node theme={null}
  import { Firecrawl } from "firecrawl";
  import { z } from "zod";

  const app = new Firecrawl({
    // No se necesita API key para comenzar — agrega una para límites de tasa más altos:
    // apiKey: "fc-YOUR_API_KEY",
  });

  const companyInfoSchema = z.object({
    company_mission: z.string(),
    supports_sso: z.boolean(),
    is_open_source: z.boolean(),
    is_in_yc: z.boolean()
  });

  const result = await app.scrape("https://firecrawl.dev/", {
    formats: [{
      type: "json",
      schema: companyInfoSchema
    }]
  });

  console.log(result);
  ```

  ```bash cURL theme={null}
  # No se necesita API key para comenzar — agrega -H "Authorization: Bearer YOUR_API_KEY" para obtener límites de tasa más altos:
  curl -X POST https://api.firecrawl.dev/v2/scrape \
      -H 'Content-Type: application/json' \
      -d '{
        "url": "https://firecrawl.dev/",
        "formats": [{
          "type": "json",
          "schema": {
            "type": "object",
            "properties": {
              "company_mission": {
                "type": "string"
              },
              "supports_sso": {
                "type": "boolean"
              },
              "is_open_source": {
                "type": "boolean"
              },
              "is_in_yc": {
                "type": "boolean"
              }
            },
            "required": [
              "company_mission",
              "supports_sso",
              "is_open_source",
              "is_in_yc"
            ]
          }
        }]
      }'
  ```
</CodeGroup>

Salida:

```json Output theme={null}
{
  "success": true,
  "data": {
    "json": {
      "company_mission": "Convertir sitios web en datos listos para LLM",
      "supports_sso": true,
      "is_open_source": true,
      "is_in_yc": true
    }
  }
}
```

<div id="json-format-options">
  ### Opciones del formato JSON
</div>

Al usar el modo JSON en v2, incluye un objeto en `formats` con el esquema incorporado directamente:

`formats: [{ type: 'json', schema: { ... }, prompt: '...' }]`

Parámetros:

* `schema`: JSON Schema que describe la salida estructurada que deseas (obligatorio para la extracción basada en un esquema).
* `prompt`: Indicaciones opcionales para guiar la extracción (también se usa para la extracción sin esquema).

**Importante:** A diferencia de v1, en v2 no existe un parámetro independiente `jsonOptions`. El esquema debe incluirse directamente dentro del objeto de formato en el array `formats`.

<Note>
  **Los atributos HTML no están disponibles en la extracción JSON.** La extracción JSON funciona sobre la conversión de la página a markdown, que solo preserva el contenido de texto visible. Los atributos HTML (por ejemplo, `data-id`, atributos personalizados en elementos) se eliminan durante la conversión y el LLM no puede verlos. Si necesitas extraer valores de atributos HTML, usa el formato `rawHtml` y analiza los atributos en el lado del cliente, o usa una acción `executeJavascript` para inyectar los valores de los atributos en texto visible antes de la extracción.
</Note>

<div id="tips-for-consistent-extraction">
  ## Consejos para una extracción consistente
</div>

Si obtienes resultados inconsistentes o incompletos al extraer JSON, estas prácticas pueden ayudar:

* **Mantén los prompts cortos y enfocados.** Los prompts largos con muchas reglas aumentan la variabilidad. En su lugar, mueve las restricciones específicas (como los valores permitidos) al esquema.
* **Usa nombres de propiedades concisos.** Evita incrustar instrucciones o listas de `enum` en los nombres de las propiedades. Usa una clave corta como `"installation_type"` y coloca los valores permitidos en un array `enum`.
* **Agrega arrays `enum` para campos restringidos.** Cuando un campo tiene un conjunto fijo de valores, enuméralos en `enum` y asegúrate de que coincidan con el texto exacto que aparece en la página.
* **Incluye manejo de valores null en las descripciones de los campos.** Agrega `"Return null if not found on the page."` a la `description` de cada campo para que el modelo no adivine valores faltantes.
* **Agrega indicaciones de ubicación.** Indica al modelo dónde encontrar los datos en la página, por ejemplo: `"Flow rate in GPM from the Specifications table."`.
* **Divide esquemas grandes en solicitudes más pequeñas.** Los esquemas con muchos campos (p. ej., 30 o más) producen resultados menos consistentes. Divídelos en 2–3 solicitudes de 10–15 campos cada una.
* **Evita `minItems`/`maxItems` en arrays.** Las palabras clave de validación de JSON Schema, como `minItems` y `maxItems`, no controlan cuánto contenido recopila el scraper. Establecer `minItems: 20` no hará que el LLM devuelva más elementos; en su lugar, puede alucinar entradas para cumplir la restricción. Elimina estas palabras clave y usa un `prompt` en su lugar (p. ej., `"Extract ALL reviews from the page. Do not skip any."`) para guiar la exhaustividad.
* **Usa `"type": "array"` para extraer listas de elementos.** Si necesitas extraer varios elementos (p. ej., una lista de personas, productos o reseñas), agrúpalos en una propiedad de tipo array con un bloque `items`. Usar `"type": "object"` para una lista devolverá solo un elemento. Consulta el ejemplo de esquema de array a continuación.

**Ejemplo de un esquema bien estructurado:**

```json theme={null}
{
  "type": "object",
  "properties": {
    "product_name": {
      "type": ["string", "null"],
      "description": "Full descriptive product name as shown on the page. Return null if not found."
    },
    "installation_type": {
      "type": ["string", "null"],
      "description": "Installation type from the Specifications section. Return null if not found.",
      "enum": ["Deck-mount", "Wall-mount", "Countertop", "Drop-in", "Undermount"]
    },
    "flow_rate_gpm": {
      "type": ["string", "null"],
      "description": "Flow rate in GPM from the Specifications section. Return null if not found."
    }
  }
}
```

**Ejemplo de cómo extraer una lista de elementos:**

Cuando una página contiene varios elementos (p. ej., miembros del equipo, productos o reseñas), usa `"type": "array"` con `"items"` para obtener la lista completa:

```json theme={null}
{
  "type": "object",
  "properties": {
    "people": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "role": { "type": "string" },
          "department": { "type": "string" }
        }
      }
    }
  }
}
```

> ¿Eres un agente de IA que necesita una clave de API de Firecrawl? Consulta [firecrawl.dev/agent-onboarding/SKILL.md](https://www.firecrawl.dev/agent-onboarding/SKILL.md) para ver las instrucciones de incorporación automatizada.
