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

# Node.js

> Use Geekflare API in any Node.js or TypeScript project — with the official SDK or raw fetch.

The official `@geekflare/api-node` SDK gives you full TypeScript support and handles auth, serialization, and response parsing out of the box. Raw `fetch` examples are included for dependency-free setups.

## Prerequisites

* Node.js **18+** (native `fetch` is stable from v18)
* A Geekflare API key — [get one free](https://dash.geekflare.com)

## Installation

<Tabs>
  <Tab title="pnpm">`bash pnpm add @geekflare/api-node `</Tab>
  <Tab title="npm">`bash npm install @geekflare/api-node `</Tab>
  <Tab title="yarn">`bash yarn add @geekflare/api-node `</Tab>
</Tabs>

## Set your API key

Create a `.env` file at your project root:

```bash .env theme={null}
GEEKFLARE_API_KEY=your_api_key_here
```

<Warning>Never commit your `.env` file. Add it to `.gitignore`.</Warning>

## Initialize the client

```ts theme={null}
import { GeekflareClient } from "@geekflare/api-node";

const client = new GeekflareClient({
  apiKey: process.env.GEEKFLARE_API_KEY!,
});
```

***

## Web Scraping

Scrape the full content of any URL. Returns HTML, Markdown, and more depending on the `format` you request.

<Tabs>
  <Tab title="SDK">
    ```ts theme={null}
    import { GeekflareClient } from "@geekflare/api-node";

    const client = new GeekflareClient({
      apiKey: process.env.GEEKFLARE_API_KEY!,
    });

    const result = await client.webScrape({
      url: "https://toscrape.com/",
      device: "desktop",
      renderJS: true,
      blockAds: true,
      format: "html,markdown",
    });

    console.log(result);
    ```
  </Tab>

  <Tab title="fetch">
    ```ts theme={null}
    const response = await fetch("https://api.geekflare.com/webscraping", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": process.env.GEEKFLARE_API_KEY!,
      },
      body: JSON.stringify({
        url: "https://toscrape.com/",
        device: "desktop",
        renderJS: true,
        blockAds: true,
        format: "html,markdown",
      }),
    });

    const result = await response.json();
    console.log(result);
    ```
  </Tab>
</Tabs>

**Key parameters:**

| Parameter      | Type                    | Description                         |
| -------------- | ----------------------- | ----------------------------------- |
| `url`          | `string`                | **Required.** The URL to scrape     |
| `device`       | `"desktop" \| "mobile"` | Emulate device type                 |
| `renderJS`     | `boolean`               | Wait for JavaScript to execute      |
| `blockAds`     | `boolean`               | Block ads before scraping           |
| `format`       | `string`                | Comma-separated: `html`, `markdown` |
| `proxyCountry` | `string`                | Route via country code, e.g. `"us"` |
| `stealth`      | `boolean`               | Enable stealth mode                 |
| `waitTime`     | `number`                | Extra wait time in seconds          |

**Example response:**

```json theme={null}
{
  "timestamp": 1779703261268,
  "apiStatus": "success",
  "apiCode": 200,
  "meta": {
    "url": "https://toscrape.com/",
    "device": "desktop",
    "format": ["html-llm"],
    "blockAds": true,
    "renderJS": true,
    "stealth": false,
    "test": { "id": "mxqx9v9y0742lap6altwdteqd28t23nq" }
  },
  "data": "https://example.com/9bulgk075ed9m3vhua5vcrp0.html"
}
```

The `data` field is a URL to the scraped output file. For full response details, see the [Web Scraping endpoint reference](https://docs.geekflare.com/api/endpoint/webscraping).

***

## Search

Run a web search and get ranked results with titles, URLs, and descriptions.

<Tabs>
  <Tab title="SDK">
    ```ts theme={null}
    import { GeekflareClient } from "@geekflare/api-node";

    const client = new GeekflareClient({
      apiKey: process.env.GEEKFLARE_API_KEY!,
    });

    const result = await client.search({
      query: "best static site generators",
      limit: 10,
      location: "us",
      source: "web",
      time: "m",     // past month
      format: "json",
    });

    console.log(result);
    ```
  </Tab>

  <Tab title="fetch">
    ```ts theme={null}
    const response = await fetch("https://api.geekflare.com/search", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": process.env.GEEKFLARE_API_KEY!,
      },
      body: JSON.stringify({
        query: "best static site generators",
        limit: 10,
        location: "us",
        source: "web",
        time: "m",
        format: "json",
      }),
    });

    const result = await response.json();
    console.log(result);
    ```
  </Tab>
</Tabs>

**Key parameters:**

| Parameter        | Type       | Description                                              |
| ---------------- | ---------- | -------------------------------------------------------- |
| `query`          | `string`   | **Required.** The search query                           |
| `limit`          | `number`   | Number of results (default: `10`)                        |
| `location`       | `string`   | Country code for localized results, e.g. `"us"`          |
| `source`         | `string`   | `"web"`, `"news"`, etc.                                  |
| `time`           | `string`   | Recency filter: `"d"` (day), `"w"` (week), `"m"` (month) |
| `includeDomains` | `string[]` | Only return results from these domains                   |
| `excludeDomains` | `string[]` | Exclude results from these domains                       |
| `groundedAnswer` | `boolean`  | Return an AI-grounded answer alongside results           |

**Example response:**

```json theme={null}
{
  "timestamp": 1779703261268,
  "apiStatus": "success",
  "apiCode": 200,
  "meta": {
    "query": "best static site generators",
    "count": 10,
    "source": "web",
    "location": "us",
    "time": "m",
    "test": { "id": "mxqx9v9y0742lap6altwdteqd28t23nq" }
  },
  "data": [
    {
      "title": "10 Best Static Site Generators in 2024",
      "url": "https://example.com/article",
      "snippet": "A comprehensive comparison of the top static site generators...",
      "date": "Dec 18, 2025",
      "position": 1,
      "content": "Full article cleaned for LLM consumption..."
    }
  ]
}
```

***

## Screenshot

Capture a screenshot of any URL. Returns a hosted image URL.

<Tabs>
  <Tab title="SDK">
    ```ts theme={null}
    import { GeekflareClient } from "@geekflare/api-node";

    const client = new GeekflareClient({
      apiKey: process.env.GEEKFLARE_API_KEY!,
    });

    const result = await client.screenshot({
      url: "https://example.com",
      type: "png",
      fullPage: true,
      device: "desktop",
      viewportWidth: 1280,
      viewportHeight: 800,
      blockAds: true,
      hideCookie: true,
      quality: 90,
    });

    console.log(result);
    ```
  </Tab>

  <Tab title="fetch">
    ```ts theme={null}
    const response = await fetch("https://api.geekflare.com/screenshot", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": process.env.GEEKFLARE_API_KEY!,
      },
      body: JSON.stringify({
        url: "https://example.com",
        type: "png",
        fullPage: true,
        device: "desktop",
        viewportWidth: 1280,
        viewportHeight: 800,
        blockAds: true,
        hideCookie: true,
        quality: 90,
      }),
    });

    const result = await response.json();
    console.log(result);
    ```
  </Tab>
</Tabs>

**Key parameters:**

| Parameter          | Type                       | Description                         |
| ------------------ | -------------------------- | ----------------------------------- |
| `url`              | `string`                   | **Required.** The URL to capture    |
| `type`             | `"png" \| "jpg" \| "webp"` | Output image format                 |
| `fullPage`         | `boolean`                  | Capture beyond the visible viewport |
| `device`           | `"desktop" \| "mobile"`    | Device emulation                    |
| `viewportWidth`    | `number`                   | Viewport width in pixels            |
| `viewportHeight`   | `number`                   | Viewport height in pixels           |
| `blockAds`         | `boolean`                  | Remove ads before capture           |
| `hideCookie`       | `boolean`                  | Hide cookie consent banners         |
| `skipCaptcha`      | `boolean`                  | Attempt to bypass CAPTCHA overlays  |
| `delay`            | `number`                   | Wait (seconds) before capture       |
| `quality`          | `number`                   | Image quality `1–100` (JPEG/WebP)   |
| `removeBackground` | `boolean`                  | Remove background (PNG only)        |

**Example response:**

```json theme={null}
{
  "timestamp": 1779703261268,
  "apiStatus": "success",
  "apiCode": 200,
  "meta": {
    "url": "https://example.com",
    "type": "png",
    "device": "desktop",
    "fullPage": true,
    "blockAds": true,
    "hideCookie": true,
    "viewportWidth": 1280,
    "viewportHeight": 800,
    "quality": 90,
    "test": { "id": "mxqx9v9y0742lap6altwdteqd28t23nq" }
  },
  "data": "https://geekflare.com/tests/screenshot/kbi6d206g87ituahb7icwtpr.png"
}
```

The `data` field is a direct URL to the screenshot image. See the [Screenshot endpoint reference](https://docs.geekflare.com/api/endpoint/screenshot).

***

## Error handling

The SDK throws on API errors. Wrap calls in `try/catch` and inspect the error for actionable codes.

```ts theme={null}
import { GeekflareClient } from "@geekflare/api-node";

const client = new GeekflareClient({
  apiKey: process.env.GEEKFLARE_API_KEY!,
});

try {
  const result = await client.webScrape({ url: "https://toscrape.com/" });
  console.log(result);
} catch (error: any) {
  console.error("API error:", error);

  const code = error?.apiCode ?? error?.status;

  switch (code) {
    case 401:
      console.error("Invalid or missing API key.");
      break;
    case 402:
      console.error("API credits exhausted. Top up at dash.geekflare.com.");
      break;
    case 403:
      console.error("This endpoint is not available on your current plan.");
      break;
    case 429:
      console.error("Rate limit exceeded. Back off and retry.");
      break;
    default:
      console.error(`Unexpected error [${code}]:`, error.message);
  }
}
```

### Common error codes

| Code  | Meaning                               |
| ----- | ------------------------------------- |
| `401` | Missing or invalid `x-api-key` header |
| `402` | API credits exhausted                 |
| `403` | Endpoint requires a higher plan       |
| `404` | Wrong endpoint URL or HTTP method     |
| `429` | Rate limit exceeded                   |

<Tip>
  See [Rate Limit Exceeded](/api/rate-limit-exceeded) and [Credit
  Exhausted](/api/credit-exhausted) for strategies to handle these gracefully.
</Tip>

***

## Next steps

* [Next.js quickstart](/api/quickstart/nextjs) — Server Actions and Route Handlers
* [NestJS quickstart](/api/quickstart/nestjs) — Injectable services and modules
* [API Reference](/api/endpoint/reference) — Full endpoint documentation
* [SDK on npm](https://www.npmjs.com/package/@geekflare/api-node)
