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

# Python SDK

> The official Python SDK for the Decodo Web Scraping API, with typed targets, IDE autocomplete, and sync, async, and batch scraping methods.

<Info>
  View the [Python SDK GitHub repository](https://github.com/Decodo/sdk-python) for the latest installation instructions, examples, and source code.
</Info>

Build typed scraping workflows for search engines, eCommerce platforms, social media, AI tools, and more with the official Decodo Python SDK for [Web Scraping API](https://decodo.com/scraping/web).

* Fully typed targets and parameters with IDE autocomplete
* Sync, async, and batch scraping methods
* Built on `httpx`; requires Python 3.12 or later
* Typed error hierarchy for safer integrations

## What is the Decodo Python SDK?

The Decodo Python SDK provides a typed interface for interacting with Decodo targets like Google, Amazon, TikTok, Reddit, YouTube, ChatGPT, Perplexity, and more. Instead of manually constructing HTTP requests and validating payloads, you work with fully typed methods and target-specific parameter classes directly in your editor.

## Why use the SDK?

* **Typing and autocomplete** – target parameters are fully typed for better editor support and fewer mistakes.
* **Unified scraping interface** – work with search engines, eCommerce platforms, social media, and AI tools through one SDK.
* **Async and batch workflows** – create scraping tasks, poll task status, and process batches at scale.
* **Typed errors** – handle authentication, validation, timeout, and rate-limit failures safely.
* **Minimal setup** – single dependency on `httpx`, no additional HTTP client required.

## Requirements

* Python 3.12+

## Installation

```bash theme={null}
pip install decodo-sdk
```

## Quick start

Create a new project:

```bash theme={null}
mkdir scrape-with-decodo
cd scrape-with-decodo
pip install decodo-sdk
touch main.py
```

Get your Web Scraping API Basic Auth token from the [**Decodo dashboard**](https://dashboard.decodo.com/welcome). Keep it out of your source by storing it in an environment variable:

```text theme={null}
export DECODO_TOKEN=your_token
```

Every target has a corresponding parameter class. Import the one you need, fill in its fields, and pass it to `scrape()`:

```python theme={null}
# main.py
from decodo import (
    DecodoClient,
    DecodoConfig,
    GoogleSearchParams,
    WebScrapingApiConfig,
)

client = DecodoClient(
    DecodoConfig(
        web_scraping_api=WebScrapingApiConfig(
            token=os.environ["DECODO_TOKEN"],
        ),
    )
)

result = client.web_scraping_api.scrape(
    GoogleSearchParams(
        query="coffee shops",
        geo="United States",
        parse=True,
    )
)

print(result)
```

Run the script:

```bash theme={null}
python main.py
```

Parameter classes are bundled with the package, so no extra step is needed after `pip install decodo-sdk`.

Each class pins its own target and accepts only the fields that target supports - your IDE flags misspelled or unsupported fields, and runtime validation catches them before the request is sent.

### Alternative: dictionary payloads

Scraping methods also accept a plain Python dictionary, validated against the bundled schema before the request is sent:

```python theme={null}
result = client.web_scraping_api.scrape({
    "target": "google_search",
    "query": "coffee shops",
    "geo": "United States",
    "parse": True,
})
print(result)
```

Use the `Target` enum instead of a raw string to avoid mistyping the target name. Typed parameter classes are recommended for anything beyond a quick experiment.

## Configuration

```python theme={null}
from decodo import (
    DecodoClient,
    DecodoConfig,
    WebScrapingApiConfig,
)

client = DecodoClient(
    DecodoConfig(
        web_scraping_api=WebScrapingApiConfig(
            token="<token>",
        ),
        timeout_ms=120_000,  # optional, request timeout in ms (default: 180000)
    )
)
```

| Parameter    | Description                                                                                  |
| ------------ | -------------------------------------------------------------------------------------------- |
| `token`      | Web Scraping API Basic Auth token (base64-encoded `user:password` string) from the dashboard |
| `timeout_ms` | Request timeout in milliseconds (default: 180000)                                            |

## Web Scraping API

Access the API via `client.web_scraping_api`.

### Sync scrape

Waits for the scraping result before returning:

```python theme={null}
from decodo import AmazonProductParams

result = client.web_scraping_api.scrape(
    AmazonProductParams(
        query="B09H74FXNW",
        parse=True,
    )
)
print(result)
```

### Async scrape

Creates a scraping task and returns immediately. You then poll for its status and results:

```python theme={null}
import time
from decodo import GoogleSearchParams

task = client.web_scraping_api.scrape_async(
    GoogleSearchParams(query="laptop reviews", parse=True)
)
task_id = task["id"]

while True:
    status = client.web_scraping_api.get_status(task_id)["status"]
    if status == "done":
        break
    if status == "faulted":
        raise RuntimeError(f"Scraping task {task_id} failed.")
    time.sleep(2)

result = client.web_scraping_api.get_results(task_id)
print(result)
```

`get_status` returns `pending`, `done`, or `faulted`.

### Batch scrape

Send multiple inputs in a single request using the batch variant of a target's parameter class. The primary input accepts a list:

```python theme={null}
import time
from decodo import GoogleSearchBatchParams

batch = client.web_scraping_api.scrape_batch(
    GoogleSearchBatchParams(query=["coffee", "tea", "juice"], parse=True)
)

for task in batch["queries"]:
    task_id = task["id"]
    while True:
        status = client.web_scraping_api.get_status(task_id)["status"]
        if status == "done":
            break
        if status == "faulted":
            raise RuntimeError(f"Scraping task {task_id} failed.")
        time.sleep(2)
    result = client.web_scraping_api.get_results(task_id)
    print(result)
```

## Targets and parameter classes

Every target in the `Target` enum has a matching parameter class. The enum member name is followed by `Params` – for example, `Target.GoogleSearch` → `GoogleSearchParams` and `Target.Chatgpt` → `ChatgptParams`. For batch calls, insert `Batch` before `Params`, as in `GoogleSearchBatchParams`.

You don't need to pass a target explicitly because each parameter class already pins its own target. For example, `GoogleSearchParams(query="coffee shops")` is sufficient on its own. The `Target` enum remains useful for dictionary payloads and for reading the `target` field from a response.

<Note>
  One target breaks the naming rule: `Target.Target` maps to `TargetStoreParams` (not `TargetParams`), to avoid a name clash. Every other target follows the pattern.
</Note>

Each target accepts one primary input parameter (`url`, `query`, `product_id`, or `prompt`) together with optional configuration.

### Search engines

| Target                        | Parameter class              | Description                       | Example input                            |
| ----------------------------- | ---------------------------- | --------------------------------- | ---------------------------------------- |
| `Target.GoogleSearch`         | `GoogleSearchParams`         | Google Search results for a query | `query="coffee shops"`                   |
| `Target.GoogleMaps`           | `GoogleMapsParams`           | Google Maps search results        | `query="coffee shops brooklyn"`          |
| `Target.GoogleShoppingSearch` | `GoogleShoppingSearchParams` | Google Shopping search results    | `query="laptop"`                         |
| `Target.GoogleSuggest`        | `GoogleSuggestParams`        | Google Autocomplete suggestions   | `query="coffee"`                         |
| `Target.GoogleLens`           | `GoogleLensParams`           | Google Lens reverse image search  | `query="https://example.com/cat.jpg"`    |
| `Target.GoogleAds`            | `GoogleAdsParams`            | Google Ads results for a query    | `query="laptop"`                         |
| `Target.BingSearch`           | `BingSearchParams`           | Bing Search results               | `query="electric vehicles"`              |
| `Target.Bing`                 | `BingParams`                 | Raw Bing URL scraping             | `url="https://bing.com/search?q=laptop"` |

### eCommerce

| Target                     | Parameter class           | Description                           | Example input                              |
| -------------------------- | ------------------------- | ------------------------------------- | ------------------------------------------ |
| `Target.AmazonProduct`     | `AmazonProductParams`     | Amazon product detail page by ASIN    | `query="B09H74FXNW"`                       |
| `Target.AmazonSearch`      | `AmazonSearchParams`      | Amazon search results                 | `query="laptop"`                           |
| `Target.AmazonPricing`     | `AmazonPricingParams`     | Amazon pricing and offers             | `query="B09H74FXNW"`                       |
| `Target.AmazonSellers`     | `AmazonSellersParams`     | Amazon seller listings                | `query="B09H74FXNW"`                       |
| `Target.AmazonBestsellers` | `AmazonBestsellersParams` | Amazon bestsellers by category        | `query="electronics"`                      |
| `Target.WalmartProduct`    | `WalmartProductParams`    | Walmart product page by product ID    | `product_id="15296401808"`                 |
| `Target.WalmartSearch`     | `WalmartSearchParams`     | Walmart search results                | `query="laptop"`                           |
| `Target.Walmart`           | `WalmartParams`           | Raw Walmart URL scraping              | `url="https://walmart.com/ip/15296401808"` |
| `Target.TargetProduct`     | `TargetProductParams`     | Target.com product page by product ID | `product_id="92186007"`                    |
| `Target.TargetSearch`      | `TargetSearchParams`      | Target.com search results             | `query="laptop"`                           |
| `Target.Target`            | `TargetStoreParams`       | Raw Target.com URL scraping           | `url="https://target.com/p/-/A-92186007"`  |
| `Target.Ecommerce`         | `EcommerceParams`         | Generic eCommerce page with parser    | `url="https://example.com/product/123"`    |

### Social media

| Target                     | Parameter class           | Description                            | Example input                                 |
| -------------------------- | ------------------------- | -------------------------------------- | --------------------------------------------- |
| `Target.RedditPost`        | `RedditPostParams`        | Reddit post by URL                     | `url="https://reddit.com/r/nba/comments/..."` |
| `Target.RedditSubreddit`   | `RedditSubredditParams`   | Reddit subreddit by URL                | `url="https://reddit.com/r/nba/"`             |
| `Target.RedditUser`        | `RedditUserParams`        | Reddit user profile by URL             | `url="https://reddit.com/user/example/"`      |
| `Target.YoutubeVideo`      | `YoutubeVideoParams`      | YouTube video by ID                    | `query="dFu9aKJoqGg"`                         |
| `Target.YoutubeSearch`     | `YoutubeSearchParams`     | YouTube search results                 | `query="ambient music"`                       |
| `Target.YoutubeMetadata`   | `YoutubeMetadataParams`   | YouTube video metadata by ID           | `query="dFu9aKJoqGg"`                         |
| `Target.YoutubeTranscript` | `YoutubeTranscriptParams` | YouTube video transcript by ID         | `query="dFu9aKJoqGg"`                         |
| `Target.YoutubeChannel`    | `YoutubeChannelParams`    | YouTube channel by handle or ID        | `query="@decodo_official"`                    |
| `Target.TiktokPost`        | `TiktokPostParams`        | TikTok post by URL                     | `url="https://www.tiktok.com/@nba/video/..."` |
| `Target.TiktokShopSearch`  | `TiktokShopSearchParams`  | TikTok Shop search results             | `query="wireless earbuds"`                    |
| `Target.TiktokShopProduct` | `TiktokShopProductParams` | TikTok Shop product page by product ID | `product_id="7100000000000000000"`            |
| `Target.Tiktok`            | `TiktokParams`            | Raw TikTok URL scraping                | `url="https://www.tiktok.com/@nba"`           |

### AI tools

| Target                | Parameter class      | Description                      | Example input                                 |
| --------------------- | -------------------- | -------------------------------- | --------------------------------------------- |
| `Target.Chatgpt`      | `ChatgptParams`      | ChatGPT response for a prompt    | `prompt="What are the top three dog breeds?"` |
| `Target.Perplexity`   | `PerplexityParams`   | Perplexity response for a prompt | `prompt="What causes seasonal allergies?"`    |
| `Target.Gemini`       | `GeminiParams`       | Gemini response for a prompt     | `prompt="What are the top three dog breeds?"` |
| `Target.GoogleAiMode` | `GoogleAiModeParams` | Google AI Mode response          | `query="What are the top three dog breeds?"`  |

### Universal scraping

| Target             | Parameter class   | Description                       | Example input                              |
| ------------------ | ----------------- | --------------------------------- | ------------------------------------------ |
| `Target.Universal` | `UniversalParams` | Any URL via the universal scraper | `url="https://example.com"`                |
| `Target.Google`    | `GoogleParams`    | Raw Google URL scraping           | `url="https://google.com/search?q=laptop"` |
| `Target.Amazon`    | `AmazonParams`    | Raw Amazon URL scraping           | `url="https://amazon.com/dp/B09H74FXNW"`   |

<Note>
  `Target.UniversalEcommerce` isn't included in the table because its parameter class `UniversalEcommerceParams` only accepts optional configuration fields such as `callback_url`, with no primary input. Use `Ecommerce` for generic product pages or `Universal` for any URL.
</Note>

For the full target list and parameter details, see [**Target list**](/docs/web-scraping-api-targets) and [**Parameters**](/docs/web-scraping-api-parameters).

## Error handling

The SDK raises typed errors that map to API error codes:

```python theme={null}
import time
from decodo import (
    AuthenticationError,
    DecodoError,
    GoogleSearchParams,
    RateLimitError,
    TimeoutError,
    ValidationError,
)

params = GoogleSearchParams(query="coffee shops", geo="United States", parse=True)

try:
    response = client.web_scraping_api.scrape(params)
except AuthenticationError:
    raise SystemExit("Invalid token. Check the Basic Auth credentials in your dashboard.")
except RateLimitError:
    time.sleep(5)
    response = client.web_scraping_api.scrape(params)
except ValidationError as err:
    print("Payload rejected:", err.errors or err)
except TimeoutError:
    print("Timed out. Increase timeout_ms or switch to scrape_async for slow targets.")
except DecodoError as err:
    print(f"Request failed with {err.status_code}: {err}")
```

| Error                 | Raised when                                                             | Useful attributes           |
| --------------------- | ----------------------------------------------------------------------- | --------------------------- |
| `AuthenticationError` | The API returns `401` or `403`                                          | `status_code`               |
| `RateLimitError`      | The API returns `429`                                                   | `status_code`               |
| `ValidationError`     | The payload fails local schema validation, or the API returns `422`     | `errors`, `status_code`     |
| `TimeoutError`        | The request exceeds `timeout_ms`                                        | none                        |
| `DecodoError`         | Any other unsuccessful response - base class for the three errors above | `status_code`, `api_status` |

<Note>
  `TimeoutError` sits outside the `DecodoError` hierarchy, so `except DecodoError` won't catch it. Handle it separately.

  Typed parameters can also fail before a request is sent. An unknown field or incorrect type raises `pydantic.ValidationError` when the parameter object is created.
</Note>

***

## Related

* [**CLI**](/docs/cli) – Run Decodo scraping workflows from the command line.
* [**TypeScript SDK**](/docs/typescript-sdk) – Integrate the Web Scraping API into TypeScript and JavaScript projects.
* [**Go SDK**](/docs/go-sdk) – Integrate the Web Scraping API into Go projects.
* [**MCP Server**](/docs/mcp) – Connect AI agents and MCP-compatible tools to Decodo.
* [GitHub repository ](https://github.com/Decodo/sdk-python)– View the Python SDK source code, examples, and latest releases.

***

<Columns cols={2}>
  <Card title="Support" href="https://direct.lc.chat/12092754" cta="Let's chat!">
    Need help or just want to say hello? Our support is available 24/7. \
    You can also reach us anytime via email at [support@decodo.com](mailto:support@decodo.com).
  </Card>

  <Card title="Feedback" href="mailto:feedback@decodo.com" cta="Share feedback">
    Can't find what you're looking for? Request an article! \
    Have feedback? Share your thoughts on how we can improve.
  </Card>
</Columns>
