# DataForSEO's own Python client against SpecStream

Date: 2026-11-10. Client: dataforseo-client (PyPI) 2.1.11, Python 3.12.

## The one line a user changes

Before:

```
Configuration(username=LOGIN, password=PASSWORD)  # host https://api.dataforseo.com
```

After:

```
Configuration(username="any", password=SPECSTREAM_KEY, host="https://api.specstream.ai/dataforseo")
```

SERP Google Organic live, regular and advanced. One task per call, as DataForSEO's live API takes; each task is one fast web search at its price: $0.005 for up to 10 results, and each started block of 10 more adds $0.006 (depth 30 is $0.017, as the cost field says). Two tasks in one call get DataForSEO's own 40000.

## Request parameters

Honoured means the check in the Measured column passed on the reply. Accepted, not applied means status 200 and the reply has the form of the same call without the parameter. Refused means the vendor's error body and status.

Counts: 8 honoured, 6 accepted, not applied, 3 refused.

| Parameter | Sent | Verdict | Measured |
|---|---|---|---|
| `keyword` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en"}` | honoured | 20000; 10 organic items |
| `location_name + language_name` | `{"keyword": "web scraping api", "location_name": "Germany", "language_name": "German"}` | honoured | 20000; results differ from the US English call: True |
| `location_code + language_code` | `{"keyword": "web scraping api", "location_code": 2276, "language_code": "de"}` | honoured | 20000; results differ from the US English call: True |
| `depth` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "depth": 30}` | honoured | 20000; 30 items for depth 30 |
| `target` | `{"keyword": "web scraping", "location_code": 2840, "language_code": "en", "target": "wikipedia.org"}` | honoured | 20000; 7 items, all on the target: True |
| `tag` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "tag": "t-1"}` | honoured | 20000; data.tag = t-1 |
| `se_domain` | `{"keyword": "web scraping api", "se_domain": "google.de", "language_code": "de"}` | honoured | 20000; results differ from the US English call: True |
| `device` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "device": "mobile"}` | accepted, not applied | 20000; the search takes no such setting |
| `os` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "os": "macos"}` | accepted, not applied | 20000; the search takes no such setting |
| `search_param` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "search_param": "&tbs=qdr:m"}` | accepted, not applied | 20000; the search takes no such setting |
| `max_crawl_pages` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "max_crawl_pages": 2}` | accepted, not applied | 20000; the search takes no such setting |
| `advanced form` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en"}` | honoured | 20000; 10 organic items |
| `advanced, group_organic_results` | `{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "group_organic_results": false}` | accepted, not applied | 20000; the search takes no such setting |
| `advanced, device mobile` | `{"keyword": "web scraping api", "location_code": 2826, "language_code": "en", "device": "mobile"}` | accepted, not applied | 20000; the search takes no such setting |
| `two tasks in one call` | `[{"keyword": "a", "location_code": 2840, "language_code": "en"}, {"keyword": "b", "location_code": 2840, "language_code": "en"}]` | refused | status_code 40000: You can set only one task at a time. |
| `depth over 200` | `[{"keyword": "web scraping api", "location_code": 2840, "language_code": "en", "depth": 300}]` | refused | task status_code 40501 |
| `wrong key` | `password=wrong` | refused | UnauthorizedException: (401) |

## Response fields

Present means the field holds a value in the replies to the calls above. Empty means it is there with no value. Absent means it is not in the reply.

Counts: 46 present, 16 empty, 0 absent.

| Field | State | Measured |
|---|---|---|
| `version` | present | top level |
| `status_code` | present | top level |
| `status_message` | present | top level |
| `time` | present | top level |
| `cost` | present | top level |
| `tasks_count` | present | top level |
| `tasks_error` | present | top level |
| `tasks` | present | top level |
| `tasks[].id` | present | each task |
| `tasks[].status_code` | present | each task |
| `tasks[].status_message` | present | each task |
| `tasks[].time` | present | each task |
| `tasks[].cost` | present | each task |
| `tasks[].result_count` | present | each task |
| `tasks[].path` | present | each task |
| `tasks[].data` | present | each task |
| `tasks[].result` | present | each task |
| `tasks[].result[].keyword` | present | each result |
| `tasks[].result[].type` | present | each result |
| `tasks[].result[].se_domain` | present | each result |
| `tasks[].result[].location_code` | present | each result |
| `tasks[].result[].language_code` | present | each result |
| `tasks[].result[].check_url` | present | each result |
| `tasks[].result[].datetime` | present | each result |
| `tasks[].result[].spell` | empty | each result |
| `tasks[].result[].refinement_chips` | empty | each result |
| `tasks[].result[].item_types` | present | each result |
| `tasks[].result[].se_results_count` | present | each result |
| `tasks[].result[].pages_count` | present | each result |
| `tasks[].result[].items_count` | present | each result |
| `tasks[].result[].items` | present | each result |
| `items[].type` | present | each organic item |
| `items[].rank_group` | present | each organic item |
| `items[].rank_absolute` | present | each organic item |
| `items[].page` | present | each organic item |
| `items[].domain` | present | each organic item |
| `items[].title` | present | each organic item |
| `items[].description` | present | each organic item |
| `items[].url` | present | each organic item |
| `items[].breadcrumb` | present | each organic item |
| `items[].position` | present | each organic item |
| `items[].xpath` | empty | each organic item |
| `items[].website_name` | present | each organic item |
| `items[].is_image` | present | each organic item |
| `items[].is_video` | present | each organic item |
| `items[].is_featured_snippet` | present | each organic item |
| `items[].is_malicious` | present | each organic item |
| `items[].is_web_story` | present | each organic item |
| `items[].pre_snippet` | empty | each organic item |
| `items[].extended_snippet` | empty | each organic item |
| `items[].images` | empty | each organic item |
| `items[].amp_version` | present | each organic item |
| `items[].rating` | empty | each organic item |
| `items[].price` | empty | each organic item |
| `items[].highlighted` | empty | each organic item |
| `items[].links` | empty | each organic item |
| `items[].faq` | empty | each organic item |
| `items[].extended_people_also_search` | empty | each organic item |
| `items[].about_this_result` | empty | each organic item |
| `items[].related_search_url` | empty | each organic item |
| `items[].timestamp` | empty | each organic item |
| `items[].rectangle` | empty | each organic item |
