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

# TypeScript SDK

> Use the cloro TypeScript/Node SDK (npm install @cloro-dev/cloro) as one typed client for Google Search, ChatGPT, Gemini, Perplexity, Copilot, Grok, AI Mode, and Google News — structured JSON back, no proxies or selectors.

The [`@cloro-dev/cloro`](https://www.npmjs.com/package/@cloro-dev/cloro) npm package is the official TypeScript/Node SDK for the cloro API — one typed client for Google Search and every AI answer engine. Each call is a single authenticated request that returns structured JSON with sources; there are no proxies, headless browsers, or selectors to maintain. It ships ESM and CommonJS builds with bundled type declarations. The source lives in the [cloro-node repository](https://github.com/cloro-dev/cloro-node).

This page is the SDK reference. For a guided walkthrough with recipes, cost math, and production patterns, see the [JavaScript & Node API guide](https://cloro.dev/integrations/javascript/). Prefer raw HTTP? Every method below maps to one endpoint you can call directly — see [Making requests](/guides/making-requests/sync).

## Prerequisites

* Node 18 or newer (uses the built-in `fetch`)
* A cloro API key from the [dashboard](https://dashboard.cloro.dev) (see [Authentication](/guides/authentication))

## Install the package

```bash theme={null}
npm install @cloro-dev/cloro
```

## Configure your API key

Set the key as an environment variable — the client reads `CLORO_API_KEY` automatically:

```bash theme={null}
export CLORO_API_KEY="YOUR_API_KEY"
```

Or pass it directly when constructing the client:

```ts theme={null}
import { Cloro } from "@cloro-dev/cloro";

const client = new Cloro({ apiKey: "YOUR_API_KEY" });
```

## Quickstart

```ts theme={null}
import { Cloro } from "@cloro-dev/cloro";

const client = new Cloro(); // reads CLORO_API_KEY

const res = await client.monitor.chatgpt({
  prompt: "What do you know about Acme Corp?",
  country: "US",
  include: { markdown: true },
});

console.log(res.result.text);
for (const source of res.result.sources) {
  console.log(source.position, source.url, source.label);
}
```

Every call resolves with the `{ success, result }` envelope. Pass `include: {...}` to request extra formats (`markdown`, `html`, `searchQueries`, `shopping`, and more, depending on the engine).

## Every engine, one client

AI engines take a `prompt`; Google Search and Google News take a `query`. Each method is a thin wrapper over one endpoint.

| Method                                           | Endpoint                                                                      |
| ------------------------------------------------ | ----------------------------------------------------------------------------- |
| `client.monitor.google({ query, country })`      | [`POST /v1/monitor/google`](/api-reference/endpoint/monitor-google)           |
| `client.monitor.chatgpt({ prompt, country })`    | [`POST /v1/monitor/chatgpt`](/api-reference/endpoint/monitor-chatgpt)         |
| `client.monitor.gemini({ prompt, country })`     | [`POST /v1/monitor/gemini`](/api-reference/endpoint/monitor-gemini)           |
| `client.monitor.perplexity({ prompt, country })` | [`POST /v1/monitor/perplexity`](/api-reference/endpoint/monitor-perplexity)   |
| `client.monitor.copilot({ prompt, country })`    | [`POST /v1/monitor/copilot`](/api-reference/endpoint/monitor-copilot)         |
| `client.monitor.grok({ prompt, country })`       | [`POST /v1/monitor/grok`](/api-reference/endpoint/monitor-grok)               |
| `client.monitor.aimode({ prompt, country })`     | [`POST /v1/monitor/aimode`](/api-reference/endpoint/monitor-aimode)           |
| `client.monitor.googleNews({ query, country })`  | [`POST /v1/monitor/google/news`](/api-reference/endpoint/monitor-google-news) |

`client.monitor.google` also accepts `location`, `uule`, `device`, and `pages` (1–20). The client exposes `client.countries()` and `client.states()` for the [supported countries](/api-reference/endpoint/countries) and states.

<Note>
  `client.monitor.grok` is available, but the provider is [temporarily unavailable](/guides/providers) — calls to it will fail until Grok access is restored.
</Note>

## Async task queue

For large batches, don't loop synchronous calls — enqueue tasks and poll them. `createBatch` submits up to 500 tasks in one request; `wait` polls a task to completion with interval backoff. See [Async requests](/guides/making-requests/async).

```ts theme={null}
import { Cloro } from "@cloro-dev/cloro";

const client = new Cloro();

const KEYWORDS = ["best running shoes", "trail running shoes", "waterproof running shoes"];

// Enqueue up to 500 tasks in a single call.
const results = await client.asyncTasks.createBatch(
  KEYWORDS.map((kw) => ({ taskType: "GOOGLE", payload: { query: kw, country: "US" } })),
);

for (const item of results) {
  if (item.success) {
    const done = await client.asyncTasks.wait(item.task.id);
    const organic = done.response.result.organicResults;
    if (organic?.length) {
      console.log(item.task.id, "→", organic[0].link);
    } else {
      console.log(item.task.id, "→ no results");
    }
  } else {
    console.log("failed:", item.error.message);
  }
}
```

For a single task, `client.asyncTasks.run({ taskType, payload })` creates it and resolves once it completes. Valid `taskType` values: `CHATGPT`, `GEMINI`, `PERPLEXITY`, `COPILOT`, `GROK`, `AIMODE`, `GOOGLE`, `GOOGLE_NEWS`.

## Reliability and configuration

The client retries timeouts, connection errors, and `429`/`5xx` responses with exponential backoff — tune it with `new Cloro({ maxRetries: 2, timeout: 60000 })` (timeout in milliseconds). Cap your own concurrency to your plan's limit (see [Concurrency](/guides/concurrency)), read the key from `CLORO_API_KEY` rather than hardcoding it, and access response fields with optional chaining (`?.`) since shapes vary by query (a Google result with no AI Overview omits `aioverview`).

## Error handling

Every error subclasses `CloroError`, so one `instanceof CloroError` check catches everything. HTTP failures map to status-specific types:

```ts theme={null}
import { Cloro, AuthenticationError, RateLimitError, CloroError } from "@cloro-dev/cloro";

const client = new Cloro();

try {
  const res = await client.monitor.chatgpt({ prompt: "...", country: "US" });
} catch (err) {
  if (err instanceof AuthenticationError) {
    // 401 — bad or missing API key
  } else if (err instanceof RateLimitError) {
    // 429 — the client already retried; back off further if it persists
  } else if (err instanceof CloroError) {
    // everything else
  } else {
    throw err;
  }
}
```

| Exception                              | Meaning                                                       |
| -------------------------------------- | ------------------------------------------------------------- |
| `AuthenticationError`                  | `401` — missing or invalid API key                            |
| `BadRequestError`                      | `400` — malformed request or failed validation                |
| `PermissionDeniedError`                | `403` — key not allowed for this action                       |
| `NotFoundError`                        | `404` — resource does not exist                               |
| `ConflictError`                        | `409` — conflicts with current state (e.g. concurrency limit) |
| `RateLimitError`                       | `429` — too many requests                                     |
| `InternalServerError`                  | `5xx` — the API failed to process the request                 |
| `APITimeoutError`                      | request timed out before a response                           |
| `TaskFailedError` / `TaskTimeoutError` | async task failed, or did not finish within the poll timeout  |

## Related

* [JavaScript & Node API guide](https://cloro.dev/integrations/javascript/) — the landing-page walkthrough with recipes, pricing, and production patterns
* [Python SDK](/integrations/python) — the same client surface in Python
* [Google SERP API](https://cloro.dev/serp-api/) — the SERP endpoint this SDK wraps

## Next steps

* [Making requests](/guides/making-requests/sync) — the raw sync and [async](/guides/making-requests/async) HTTP contracts
* [Providers](/guides/providers) and [Billing & credits](/guides/billing) — per-engine credit costs
* [API reference](/api-reference/endpoint/monitor-google) — full request and response schemas
* [cloro-node on GitHub](https://github.com/cloro-dev/cloro-node) and [on npm](https://www.npmjs.com/package/@cloro-dev/cloro)
