# Tavily Map's Python client against SpecStream

Date: 2026-11-10. Client: tavily-python 0.8.5.

## The one line a user changes

Before:

```
TavilyClient(api_key="tvly-...")
```

After:

```
TavilyClient(api_key=KEY, api_base_url="https://api.specstream.ai/tavily")
```

The same address serves Tavily's search and extract. A map names the start address first, as Tavily's does, and is one page read when the site gives a link of its own. Depth 1 is the start page's links; a deeper map adds the pages the site's sitemaps publish. Tavily's crawl (`/crawl`) is not served at this address.

## 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: 9 honoured, 6 accepted, not applied, 3 refused.

| Parameter | Sent | Verdict | Measured |
|---|---|---|---|
| `url` | `https://quotes.toscrape.com/` | honoured | status 200; 47 URLs, each a string on the site |
| `url (a bare host)` | `quotes.toscrape.com` | honoured | status 200; 47 URLs |
| `url (a page with no links)` | `https://example.com` | honoured | status 200; 1 URL, the start address |
| `limit` | `5` | honoured | status 200; 5 URLs |
| `max_depth` | `2` | honoured | status 200; 500 URLs, 22 at depth 1 |
| `select_paths` | `/author/.*` | honoured | status 200; 8 URLs, each under /author/ |
| `exclude_paths` | `/tag/.*` | honoured | status 200; 11 URLs, none under /tag/ |
| `select_domains` | `^quotes\.toscrape\.com$` | honoured | status 200; 47 URLs on the host |
| `exclude_domains` | `^quotes\.toscrape\.com$` | honoured | status 200; 0 URLs on the host |
| `max_breadth` | `5` | accepted, not applied | status 200; reply has the baseline's form |
| `instructions` | `pages about authors` | accepted, not applied | status 200; reply has the baseline's form |
| `allow_external` | `false` | accepted, not applied | status 200; reply has the baseline's form |
| `include_images` | `true` | accepted, not applied | status 200; reply has the baseline's form |
| `include_usage` | `true` | accepted, not applied | status 200; reply has the baseline's form |
| `timeout` | `60` | accepted, not applied | status 200; reply has the baseline's form |
| `select_paths (a bad pattern)` | `([` | refused | status 400; BadRequestError |
| `max_depth (past 5)` | `6` | refused | status 400; BadRequestError |
| `api key (wrong key)` | a key that is not one | refused | status 401; InvalidAPIKeyError |

## 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: 4 present, 0 empty, 1 absent.

| Field | State | Measured |
|---|---|---|
| `base_url` | present | every 200 reply |
| `results` | present | every 200 reply |
| `response_time` | present | every 200 reply |
| `request_id` | present | every 200 reply |
| `usage` | absent | every 200 reply |
