scrape
Extracción multiformato unificada con una sola descarga. Pida a una única carga de página markdown, HTML, HTML sin procesar, texto, enlaces, metadatos, una captura de pantalla o JSON: todos los formatos solicitados se sirven desde la misma descarga, y un formato que falle se devuelve como aviso en lugar de hacer fallar toda la llamada. Añada un formato highlights o question con una consulta para obtener solo las frases, filas de tabla y bloques de código que coinciden —texto literal de la página con un desplazamiento en el markdown, sin ningún modelo por medio— por 1 credit más. Pase escalate: true y una página que llega como un muro antibots en lugar de como la página se vuelve a descargar una vez a través del navegador stealth dentro de la misma llamada, por 5 credits más.
Casos de uso
Una llamada en lugar de cuatro
Obtenga markdown, enlaces y metadatos de una página en una sola solicitud en lugar de encadenar fetch_url, extract_links y extract_metadata.
Markdown listo para LLM
Solicite markdown con onlyMainContent activado para enviar texto de página limpio y sin plantilla directamente a una canalización RAG o a un prompt.
Instantáneas de archivo
Pida rawHtml y markdown juntos para conservar el código fuente exacto junto a una copia legible, desde una sola descarga.
Una descarga, muchos formatos
Seis formatos cuestan los mismos 2 credits que uno, así que un pipeline que necesita markdown, links y metadata debería pedir los tres en una sola llamada en lugar de tres.
Cite la página, no la resuma
Pida highlights con una consulta, o question con una pregunta, para obtener solo las frases, filas de tabla y bloques de código que coinciden: texto literal de la página con un desplazamiento en el markdown de la misma llamada, de modo que un agente cita la fuente en lugar de parafrasearla. A diferencia de las herramientas de descarga que resumen, no hay ningún modelo por medio.
Endpoint
/api/v1/tools/scrapeParameters
highlights o question acotado a una consulta añade 1 credit, cobrado una sola vez por solicitud tanto si incluye uno como los dos. Con escalate: true, la proyección es el techo: 7 credits, u 8 junto con un formato acotado a una consulta; los 5 credits de la etapa de escalada solo se cobran si la descarga simple quedó bloqueada y la etapa llegó a ejecutarse.| Name | Type | Required | Default | Description |
|---|---|---|---|---|
url | string | Required | - | La URL que se va a extraer (debe incluir el protocolo: http:// o https://) Example: https://example.com |
formats | array | Optional | ["markdown"] | Formatos de salida que se devolverán. Uno o varios de `markdown`, `html`, `rawHtml`, `text`, `links`, `metadata`, más dos formatos de objeto acotados a una consulta: `{ "type": "highlights", "query": "…", "max_highlights": 10, "mode": "extractive" }` devuelve las frases y bloques de código que mejor coinciden con `query` (`max_highlights` de 1 a 50, por defecto 10): `kind` es `sentence` o `code_block` en la API REST alojada; las unidades `table_row` las devuelve el servidor MCP, cuyo markdown conserva las tablas como filas con barras verticales, mientras que la API REST aplana las tablas a texto; y `{ "type": "question", "question": "…", "mode": "extractive" }` devuelve un `answer` compuesto por los pasajes que mejor coinciden. Ambos devuelven texto literal de la página; cada unidad lleva un `offset` y un `length` que apuntan al formato `markdown` de la misma llamada (con el mismo ajuste de `onlyMainContent`), así que pida también `markdown` para citar con un localizador. `mode: "model"` se rechaza aquí con 400: necesita un LLM y solo está disponible en el servidor MCP. `screenshot` y `json-schema` superan la validación pero después se rechazan con 400: necesitan un navegador o un LLM, que la API REST alojada no proporciona. Example: ["markdown", { "type": "highlights", "query": "Starter plan price" }, { "type": "question", "question": "How much does the Starter plan cost?" }] |
onlyMainContent | boolean | Optional | true | Elimina la navegación, los encabezados y los pies de página para devolver solo el contenido principal del artículo. Example: true |
escalate | boolean | Optional | false | Active un único reintento automático a través del navegador stealth cuando la descarga simple devuelve un muro antibots en lugar de la página: una página de desafío de Cloudflare, Amazon, DataDome, PerimeterX, Akamai o Vercel, un armazón vacío o un marcador de posición corto con título de error. La descarga simple siempre se ejecuta primero; solo cuando queda bloqueada, la misma llamada renderiza la página con el navegador stealth y deriva de lo renderizado todos los formatos solicitados, de modo que una página bloqueada cuesta una llamada en lugar de dos. La escalada reutiliza la misma ruta stealth que [stealth_mode](/docs/api-reference/tools/stealth-mode) y la misma comprobación de robots.txt, y no añade ningún tratamiento nuevo de una defensa antibots. Un muro en el que también se rechaza el renderizado stealth sigue devolviéndose como página bloqueada, con `escalated: true` y sin cobro alguno: la escalada ahorra la segunda llamada, no garantiza la página. Es más fiable cuando la descarga simple falló solo porque la página necesita JavaScript para renderizarse. La respuesta incluye entonces `escalated` y, cuando vale `true`, `stealth`. Añade 5 credits, que solo se cobran si la etapa de escalada llega a ejecutarse. Solo en el servidor MCP, un host que haya bloqueado una petición se recuerda durante 24 horas, de modo que la siguiente llamada con `escalate: true` a ese host se salta la descarga simple condenada al fracaso y lo indica en un aviso. Example: true |
escalate_engine | string | Optional | playwright | Motor de navegador para la etapa de escalada: "playwright" (por defecto) o "camoufox" (basado en Firefox, con mayor resistencia a la detección; disponible solo donde esté instalado en el backend). Se ignora salvo que `escalate` sea `true` y la descarga simple haya quedado bloqueada. Example: camoufox |
respect_robots | boolean | Optional | true | Respeta el robots.txt del sitio de destino. Con el valor `true`, una ruta que robots.txt no permita a `CrawlForge` se rechaza con un 403 antes de descargar nada y no se cobran credits. Póngalo en `false` solo para destinos con los que tenga su propio acuerdo: la respuesta incluye entonces una entrada `warnings` y la anulación queda registrada en su API key. Example: true |
max_inline_chars | number | Optional | 40000 | Tamaño máximo del resultado que se devuelve en línea, en caracteres de su JSON (de 1.000 a 10.000.000). Por encima, la respuesta incluye `preview` (los primeros `max_inline_chars` caracteres del markdown), `result_handle`, `total_chars`, `truncated: true` y `expires_at`, y [read_result](/docs/api-reference/tools/read-result) lee el resto por 1 credit por llamada. Los resultados almacenados se conservan 1 hora. Example: 40000 |
redact_pii | boolean | object | Optional | false | Elimine los datos personales del texto que devuelve esta llamada, antes de que el resultado se almacene o se envíe de vuelta. `true` es la forma abreviada de `{ mode: "fast" }`: las cuatro clases de expresiones regulares, etiquetadas. Siempre que pida redacción, la respuesta lleva `redaction: { entities, count, mode }` dentro de `data`, incluso cuando no hubo coincidencias (`count: 0`), de modo que «no se encontró nada» nunca se confunde con «se ignoró el parámetro»; una clase sin coincidencias se omite en lugar de informarse como `0`. La redacción se ejecuta **antes** de almacenar el resultado, así que un resultado grande que se lea después con [read_result](/docs/api-reference/tools/read-result) ya viene redactado. Dos límites deliberados: las direcciones (`url`, `link`, `href`, `canonical_url`) nunca se redactan, y los contadores derivados del texto (`content_length`, `word_count`, `character_count`) lo describen tal como se extrajo, antes de la redacción. Example: true |
Ejemplos de solicitud
cURL
curl -X POST https://crawlforge.dev/api/v1/tools/scrape \
-H "X-API-Key: cf_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"formats": [
"markdown", "links", "metadata",
{ "type": "highlights", "query": "professional plan price per month" }
],
"onlyMainContent": true,
"escalate": true
}'TypeScript
// npm install crawlforge-sdk
import { CrawlForge, ToolError } from 'crawlforge-sdk';
const client = new CrawlForge({ apiKey: process.env.CRAWLFORGE_API_KEY });
try {
const result = await client.scrape({
url: 'https://example.com',
formats: [
'markdown', 'links', 'metadata',
// 1 extra credit: the matching sentences, table rows and code blocks, verbatim, with offsets
{ type: 'highlights', query: 'professional plan price per month' },
],
onlyMainContent: true,
// Only when the plain fetch meets a bot wall: one stealth render in this same call (5 extra credits)
escalate: true,
});
// result.data is untyped in crawlforge-sdk 0.1 — its shape is the Response Example below.
const { formats } = result.data as {
formats: { markdown: string; links: string[]; metadata: { title: string }; highlights: { text: string }[] };
};
console.log('Markdown:', formats.markdown);
console.log('Links found:', formats.links.length);
console.log('Title:', formats.metadata.title);
// Each highlight is verbatim page text; offset/length index formats.markdown.
console.log('Best match:', formats.highlights[0]?.text);
// A success with warnings is a PARTIAL result — some formats came back, others didn't.
if (result.warnings.length > 0) {
console.warn('Partial result:', result.warnings);
}
console.log('Credits used:', result.creditsUsed);
console.log('Credits remaining:', result.creditsRemaining);
} catch (err) {
// A bot wall the stealth render could not pass either: not charged, blocked.vendor names it.
if (err instanceof ToolError && err.blocked) {
console.error('Blocked by', err.blocked.vendor, '— escalated:', err.escalated);
} else {
throw err;
}
}Python
# pip install crawlforge
from crawlforge import CrawlForge, ToolError
client = CrawlForge() # reads CRAWLFORGE_API_KEY
try:
result = client.scrape(
url='https://example.com',
formats=[
'markdown', 'links', 'metadata',
# 1 extra credit: the matching sentences, table rows and code blocks, verbatim, with offsets
{'type': 'highlights', 'query': 'professional plan price per month'},
],
onlyMainContent=True,
# Only when the plain fetch meets a bot wall: one stealth render in this same call (5 extra credits)
escalate=True,
)
except ToolError as e:
# A bot wall the stealth render could not pass either: not charged, blocked names the vendor.
print(f"Blocked: {e.blocked} (escalated: {e.escalated})")
raise
# result.data is a plain dict — its shape is the Response Example below.
formats = result.data['formats']
print(f"Markdown: {formats['markdown']}")
print(f"Links found: {len(formats['links'])}")
print(f"Title: {formats['metadata']['title']}")
# Each highlight is verbatim page text; offset/length index formats['markdown'].
print(f"Best match: {formats['highlights'][0]['text']}")
# A success with warnings is a PARTIAL result — some formats came back, others didn't.
if result.warnings:
print(f"Partial result: {result.warnings}")
print(f"Credits used: {result.credits_used}")
print(f"Credits remaining: {result.credits_remaining}")Ejemplo de respuesta
{ "success": true, "data": { "url": "https://example.com", "formats": { "markdown": "# Example\n\nMain content scraped from https://example.com. The Starter plan costs $12 per month and includes three seats. Annual billing lowers the Starter plan to $10 per month.", "highlights": [ { "text": "The Starter plan costs $12 per month and includes three seats.", "kind": "sentence", "offset": 58, "length": 62, "score": 6.612 }, { "text": "Annual billing lowers the Starter plan to $10 per month.", "kind": "sentence", "offset": 121, "length": 56, "score": 5.809 } ], "answer": { "text": "The Starter plan costs $12 per month and includes three seats.", "grounded": true, "evidence": [ { "text": "The Starter plan costs $12 per month and includes three seats.", "kind": "sentence", "offset": 58, "length": 62, "score": 6.612 } ] } }, "escalated": true, "stealth": { "engine": "playwright", "vendor_detected": "cloudflare" }, "scraped_at": "2026-08-26T14:30:00.000Z" }, "credits_used": 8, "credits_remaining": 992, "processing_time": 4218}data.urlLa URL que se descargó.data.formatsUna clave por formato solicitado: el contenido extraído está aquí dentro, no en el nivel superior de data.data.formats.markdownContenido principal convertido a markdown (presente cuando se solicita `markdown`).data.formats.highlightsLas frases y bloques de código mejor clasificados que coinciden con `query`, literales (presente cuando se solicita un formato `highlights`). Cada unidad lleva `text`, `kind` (`sentence` o `code_block` en la API REST alojada; las unidades `table_row` las devuelve el servidor MCP, cuyo markdown conserva las tablas como filas con barras verticales, mientras que la API REST las aplana a texto), `offset`, `length` y `score`: un valor de relevancia BM25 sin normalizar, útil solo para ordenar, no una confianza de 0 a 1.data.formats.highlights.offsetÍndice de carácter en el formato `markdown` de la misma llamada (con el mismo ajuste de `onlyMainContent`): `markdown.slice(offset, offset + length) === text`.data.formats.answerLa respuesta a `question` (presente cuando se solicita un formato `question`): `text` es la unión de la mejor evidencia, y `evidence` enumera hasta 5 unidades de apoyo.data.formats.answer.groundedSiempre `true` en la API REST: el texto es contenido literal de la página, no se sintetiza nada.data.escalatedSi se ejecutó la etapa de escalada (presente solo cuando la solicitud incluía `escalate: true`). `false` significa que la descarga simple devolvió la página y solo se cobró el coste base.data.stealthCómo se renderizó la página (presente solo cuando `escalated` vale `true`): `engine` es el navegador que se ejecutó y `vendor_detected` nombra al proveedor de defensa antibots con el que topó la descarga simple — `cloudflare`, `amazon`, `datadome`, `perimeterx`, `akamai` o `vercel` — o `null` cuando el muro era un armazón vacío o un marcador de posición de error en lugar de un desafío con nombre.data.scraped_atMarca de tiempo ISO 8601 de la descarga.credits_usedCredits descontados por esta solicitud: 2 por scrape, sin importar cuántos formatos haya pedido, más 1 cuando se incluye un formato `highlights` o `question`, más 5 cuando se ejecutó la etapa de escalada. Aquí: 2 + 1 + 5.credits_remainingSu saldo restante de credits.Manejo de errores
Entrada no válida (400 Bad Request)
El formato de la URL no es válido, formats contiene un valor fuera de la lista admitida, o un formato highlights o question pide mode: "model", que necesita un LLM y solo está disponible en el servidor MCP. Se requiere al menos un formato cuando se envía el campo.
URL bloqueada (403 Forbidden)
El destino se resolvió en una dirección privada, interna o de enlace local y fue rechazado por la protección SSRF. Solo se pueden extraer URLs accesibles públicamente.
Credits insuficientes (402 Payment Required)
Su cuenta no tiene suficientes credits. Compre más credits o mejore su plan.
Límite de velocidad superado (429 Too Many Requests)
Ha superado el límite de velocidad de su plan. Espere un momento o mejore su plan para obtener límites más altos.
Backend de escalada no configurado (503 TOOL_NOT_AVAILABLE)
escalate: true ejecuta su etapa stealth en el backend de ejecución de CrawlForge. Cuando ese backend no está configurado, la etapa devuelve 503 y no se cobra ningún credit por ella.
Bloqueado por robots.txt (403 Forbidden)
El robots.txt del sitio de destino no permite esta ruta a CrawlForge. Establezca respect_robots: false para anularlo si tiene su propio acuerdo con el destino: la anulación queda registrada en su API key. La anulación no alcanza a un host incluido en la lista de exclusión permanente de CrawlForge, que se rechaza sea cual sea el valor de respect_robots.
markdown, links y metadata juntos cuesta los mismos 2 credits que solicitar uno solo: todos los formatos se derivan de una única descarga de la página. Pida en una sola llamada todo lo que pueda necesitar; un formato highlights o question añade 1 credit una sola vez, no por formato.Coste en credits
highlights o question añade 1 credit, cobrado una sola vez por solicitud tanto si incluye uno como los dos. Una llamada con escalate: true proyecta hasta 7 credits, u 8 junto con un formato acotado a una consulta, y solo paga el suplemento de 5 credits de escalada cuando la descarga simple devolvió un muro antibots y la etapa stealth se ejecutó: nunca más de lo proyectado.Plan Free: 1,000 credits por única vez = 500 solicitudes
Plan Hobby: 5.000 credits/mes = 2.500 solicitudes (19 USD/mes)
Plan Professional: 50.000 credits/mes = 25.000 solicitudes (99 USD/mes)
Plan Business: 250.000 credits/mes = 125.000 solicitudes (399 USD/mes)