Skip to main content

xdive

Python client for XDive: scrape pages to Markdown, crawl and map sites, search the web, and answer questions with verified citations. Synchronous and asynchronous clients, typed errors, automatic retries, and LangChain and LlamaIndex integrations.

Full documentation: https://crawler.mehdisadeghian.com/docs/sdk-python

Install

pip install xdive
pip install "xdive[langchain]"     # LangChain tools and document loader
pip install "xdive[llama-index]"   # LlamaIndex reader

Requires Python 3.9 or later. The only runtime dependency is httpx.

Quickstart

from xdive import XDive, page_markdown

with XDive() as xdive:  # reads XDIVE_API_KEY
    page = xdive.scrape("https://example.com", formats=["markdown", "links"])
    print(page_markdown(page))
    site = xdive.crawl("https://docs.example.com", max_pages=50)  # waits for the crawl
    answer = xdive.research("What does PEP 639 change about license metadata?")
    print(answer["answer"])
    for citation in answer["citations"]:
        print(citation["number"], citation["url"])

Create an API key under API Keys in the dashboard. A key belongs to one organization; the client looks the organization up once through GET /whoami, so the key is all you configure.

Configuration

Argument Environment variable Default Description
api_key XDIVE_API_KEY (or CRAWLER_API_KEY) (required) Organization API key (ck_live_…).
base_url XDIVE_BASE_URL (or CRAWLER_BASE_URL) https://crawler.mehdisadeghian.com/api API base URL, including /api.
org_id discovered Skip the /whoami lookup when you know the organization id.
timeout 120.0 Per-request timeout in seconds.
max_retries 3 Retries of overload responses: 429, and 503 with code SERVER_BUSY.

A missing key raises ValueError when the client is created.

Methods

XDive and AsyncXDive have the same methods; on AsyncXDive each is a coroutine. Keyword options are passed through as the API's JSON fields.

Method API call Returns
whoami() GET /whoami The key's organization, scopes and plan.
scrape(url, formats=None, **options) POST /orgs/{id}/scrape The page object (data).
crawl(url, *, timeout=600, poll_interval=2, **options) POST /orgs/{id}/crawl, then polls The finished crawl record with results.
start_crawl(url, **options) POST /orgs/{id}/crawl The crawl id.
get_crawl(crawl_id) GET /orgs/{id}/crawls/{crawlId} The crawl record.
wait_for_crawl(crawl_id, *, timeout=600, poll_interval=2) polls GET /orgs/{id}/crawls/{crawlId} The finished crawl record.
cancel_crawl(crawl_id) DELETE /orgs/{id}/crawls/{crawlId} None.
crawl_errors(crawl_id) GET /orgs/{id}/crawls/{crawlId}/errors Failed pages (errors) and robots_blocked URLs.
batch_scrape(urls, *, wait=True, timeout=600, **options) POST /orgs/{id}/batch/scrape The finished record, or the job id with wait=False.
map(url, *, search=None, limit=None, max_depth=None) POST /orgs/{id}/map A list of URLs.
search(query, **options) POST /orgs/{id}/search The search response with results.
research(query, *, depth="quick", output=None, schema=None, **options) POST /orgs/{id}/research answer or data, citations, sources, confidence, usage.
extract(urls, *, prompt=None, schema=None, **options) POST /orgs/{id}/extract The extracted data.
llms_txt(url, *, max_urls=None, full_text=False) POST /orgs/{id}/llmstxt llms_txt (and llms_full_txt).

XDive.org_id is a property; on AsyncXDive it is a coroutine, await client.org_id().

formats takes the API's format names (markdown, text, html, rawHtml, links, images, json, summary, question, highlights, branding, audio, screenshot, product, menu) or dicts such as {"type": "json", "schema": {...}}. page_markdown(page) returns a page's Markdown whichever field carries it (artifacts.markdown.content or markdown).

Async

import asyncio
from xdive import AsyncXDive

async def main():
    async with AsyncXDive() as client:
        pages = await asyncio.gather(*(client.scrape(u) for u in ["https://a.example", "https://b.example"]))

asyncio.run(main())

Close clients you do not use as context managers: xdive.close() or await client.aclose().

Errors and retries

Exception When Attributes
XDiveError Any API error (status 400 and above). Base class of the others. status, message, code
RateLimited Still overloaded (429, or 503 with code SERVER_BUSY) after max_retries retries. retry_after (seconds)
QuotaExceeded 402: the organization's monthly quota is used up.
CrawlTimeout crawl, wait_for_crawl or batch_scrape waited longer than timeout. The job keeps running on the server. crawl_id

Only overload is retried: a 429 (organization rate or concurrency limit) and a 503 whose JSON body has the code SERVER_BUSY (server at capacity). The client waits the number of seconds in the response's Retry-After header (1 second when absent) before each retry. Every other error, including any other 503 (for example a feature the server has not configured), raises XDiveError at once with the API's status, message and code. Network errors and timeouts surface as httpx exceptions.

Crawl polling sends If-None-Match, so an unchanged status comes back as an empty 304, and waits the interval the server sets in Retry-After, falling back to poll_interval.

Integrations

from xdive.langchain import XDiveLoader, XDiveResearchTool, XDiveScrapeTool, XDiveSearchTool

tools = [XDiveSearchTool(), XDiveScrapeTool(), XDiveResearchTool()]
docs = XDiveLoader("https://docs.example.com", mode="crawl", max_pages=100).load()
from xdive.llama_index import XDiveReader

documents = XDiveReader().load_data("https://docs.example.com", mode="crawl", max_pages=100)

XDiveSearchTool returns each result's query-relevant passages rather than whole pages, which keeps an agent's context small. See the LangChain and LlamaIndex guides.

Self-hosted

xdive = XDive(api_key="ck_live_…", base_url="https://your-host/api")

or set XDIVE_BASE_URL=https://your-host/api.

Development

pip install -e ".[dev]"
pytest

License

MIT. The license text is in the LICENSE file included in the package.

Metadata

Release files for xdive 1.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for xdive 1.5.0
File Size Uploaded Provenance Actions
xdive-1.5.0.tar.gz 17.6 kB Without provenance Details for xdive-1.5.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for xdive 1.5.0
File Interpreter ABI Platform Actions
xdive-1.5.0-py3-none-any.whl Python 3 none any Details for xdive-1.5.0-py3-none-any.whl

Total release size: 32.0 kB

Release files / xdive-1.5.0.tar.gz

Download URL xdive-1.5.0.tar.gz
Size 17.6 kB
Tags Source
SHA-256 checksum
How to use checksums
5ad85c69f1012775098dc2784977c33b0fc704df82fe74a37fa1d4b1c1b84f52
BLAKE2b-256 checksum
How to use checksums
5d5f4d82f4c6b05de6368420206081184f36620aeb54708c4dfc0f7e9a6d0ffc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / xdive-1.5.0-py3-none-any.whl

Download URL xdive-1.5.0-py3-none-any.whl
Size 14.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e5cd1e20c22c387822bc6b179e158662df39a67168b14e96027bd958f26784a
BLAKE2b-256 checksum
How to use checksums
321b6a0b0ae058427cf1d14b38abbca85023ea4ee2fa628d1ded711aa6992c8e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Security for xdive 1.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.5.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page