> ## 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.

# Python SDK

> Use the cloro Python SDK (pip install cloro) as one client for Google Search, ChatGPT, Gemini, Perplexity, Copilot, Grok, AI Mode, and Google News — structured JSON back, no proxies or selectors.

The [`cloro`](https://pypi.org/project/cloro/) Python package is the official 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. The source lives in the [cloro-python repository](https://github.com/cloro-dev/cloro-python).

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

## Prerequisites

* Python 3.8 or newer
* A cloro API key from the [dashboard](https://dashboard.cloro.dev) (see [Authentication](/guides/authentication))

## Install the package

```bash theme={null}
pip install 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:

```python theme={null}
from cloro import Cloro

client = Cloro(api_key="YOUR_API_KEY")
```

## Quickstart

```python theme={null}
from cloro import Cloro

client = Cloro()  # reads CLORO_API_KEY

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

print(res["result"]["text"])
for source in res["result"]["sources"]:
    print(source["position"], source["url"], source["label"])
```

Every call returns 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.google_news(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. `create_batch` submits up to 500 tasks in one request; `wait` polls a task to completion with interval backoff. See [Async requests](/guides/making-requests/async).

```python theme={null}
from cloro import Cloro

client = Cloro()

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

# Enqueue up to 500 tasks in a single call.
results = client.async_tasks.create_batch(
    [{"task_type": "GOOGLE", "payload": {"query": kw, "country": "US"}} for kw in KEYWORDS]
)

for item in results:
    if item["success"]:
        done = client.async_tasks.wait(item["task"]["id"])
        organic = done["response"]["result"]["organicResults"]
        if organic:
            print(item["task"]["id"], "→", organic[0]["link"])
        else:
            print(item["task"]["id"], "→ no results")
    else:
        print("failed:", item["error"]["message"])
```

For a single task, `client.async_tasks.run(task_type=..., payload=...)` creates it and blocks until it completes. Valid `task_type` 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 `Cloro(max_retries=2, timeout=60.0)`. 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 `.get()` since shapes vary by query (a Google result with no AI Overview omits `aioverview`).

## Error handling

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

```python theme={null}
from cloro import Cloro, AuthenticationError, RateLimitError, CloroError

client = Cloro()

try:
    res = client.monitor.chatgpt(prompt="...", country="US")
except AuthenticationError:
    ...  # 401 — bad or missing API key
except RateLimitError:
    ...  # 429 — the client already retried; back off further if it persists
except CloroError as exc:
    ...  # everything else
```

| 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

* [Python API guide](https://cloro.dev/integrations/python/) — the landing-page walkthrough with recipes, pricing, and production patterns
* [Python web scraping pillar](https://cloro.dev/blog/web_scraping_with_python/) — Python data-extraction fundamentals
* [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-python on GitHub](https://github.com/cloro-dev/cloro-python) and [on PyPI](https://pypi.org/project/cloro/)
