scrapedatshi ninja icon scrapedatshi
🚀 Get API Key Sign in →

One API key unlocks all tools — scraping, PDF extraction, RAG chunking, vector injection, and more. No credit card required.

🐍 Python SDK pip install scrapedatshi Typed models · Sync + Async · IDE autocomplete
PyPI → GitHub →
🤖 Claude MCP pip install scrapedatshi-mcp Use all tools directly inside Claude Desktop
PyPI → Docs →

Dev Docs

All endpoints require your API key in the request header: X-API-Key: YOUR_KEY

Scrape any URL and receive clean Markdown — stripped of ads, nav bars, and boilerplate.

Endpoint

GET https://www.scrapedatshi.com/scrape?url=TARGET_URL

Optional Parameters

Parameter Type Description
selector string A CSS selector to target a specific element (e.g. article, main, #content). Reduces noise and saves LLM tokens.

Response Shape

{
  "authenticated_user": "your_name",
  "url": "https://example.com/",
  "selector": null,
  "selectors_found": ["article", "main", "#post-content", ".entry-body"],
  "metadata": {
    "title": "Page Title",
    "description": "Page description...",
    "author": "Author Name",
    "published_date": "2026-06-09",
    "site_name": "Example Site"
  },
  "markdown": "# Page Title\n\nContent..."
}

selectors_found — a ranked list of CSS selectors detected on the page that are likely to contain main content. Use these to make a second targeted request and reduce noise in your LLM context.


The Python SDK wraps the /v1/* pipeline endpoints. The Web Scraper is a public REST tool — use the raw example below, or use client.pipeline.chunk_url() to scrape and chunk in one call.

from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()

# chunk_url() scrapes + chunks in one call (all tiers)
result = client.pipeline.chunk_url("https://www.example.com/")
print(f"Got {result.total_chunks} chunks from {result.source}")

Extract all text from a PDF — by URL or file upload. Returns plain text with optional heading detection.

Endpoint

POST https://www.scrapedatshi.com/api/pdf/text

Request Body (multipart/form-data)

Field Type Description
url string URL of the PDF to fetch. Use either url or pdf_file.
pdf_file file Upload a PDF file directly (max 20 MB).
preserve_headings bool If true, detects larger text as headings and prefixes them with #. Default: false.

Response Shape

{
  "authenticated_user": "your_name",
  "source": "https://example.com/document.pdf",
  "preserve_headings": false,
  "text": "Full extracted text content..."
}

The Python SDK wraps the /v1/* pipeline endpoints. For PDF text extraction, use the raw REST example below. To chunk a PDF file with the SDK, use client.pipeline.chunk_file().

from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()

# chunk_file() parses + chunks a local PDF (all tiers)
result = client.pipeline.chunk_file("./report.pdf")
print(f"Got {result.total_chunks} chunks from {result.source}")

Scrape any URL and receive the content pre-split into RAG-optimized chunks — ready to insert directly into Pinecone, Chroma, Qdrant, or any vector database. Tables and code blocks are never split mid-structure, preserving relational context for accurate LLM retrieval.

Endpoint

POST https://www.scrapedatshi.com/v1/rag-chunk

Send a JSON body with Content-Type: application/json.

Request Body (application/json)

Field Type Description
url string Required. The URL to scrape and chunk. Must include protocol (https://).
selector string Optional CSS selector to target a specific element before chunking (e.g. article).
chunk_size int Target tokens per chunk. Default: 512. Range: 64–4096.
overlap int Token overlap between consecutive chunks. Default: 50. Must be less than chunk_size.
js_render bool If true, uses a headless Chromium browser to render JavaScript before scraping. Required for SPAs. Adds a $0.0050 surcharge.
contextual_retrieval bool If true, generates per-chunk LLM context (RAG 2.0). Requires llm_provider, llm_api_key, and llm_model. Billed at $0.0010 per enriched chunk.
llm_provider string LLM provider for contextual retrieval. One of: openai, anthropic, gemini, cohere, mistral.
llm_api_key string Your LLM provider API key (required when contextual_retrieval=true).
llm_model string Model name for contextual retrieval (required when contextual_retrieval=true). Check your provider's docs for available models.

Response Shape

{
  "authenticated_user": "your_name",
  "url": "https://example.com/article",
  "selector": null,
  "chunk_size_target": 512,
  "overlap_tokens": 50,
  "contextual_retrieval": false,
  "chunk_count": 7,
  "total_tokens_estimated": 3421,
  "credits_used": 0.0055,
  "credits_remaining": 9.9945,
  "metadata": { ... },
  "chunks": [
    {"index": 0, "token_estimate": 487, "text": "Location: Article Title > Section\n\nFirst paragraph..."},
    ...
  ]
}

Smart guardrails: Tables and code fences are kept as single atomic units — never split across chunk boundaries. Each chunk is prefixed with a heading breadcrumb (Location: Title > Section) so the embedding model knows exactly where in the document the chunk lives.

RAG 2.0 — Contextual Retrieval: Set contextual_retrieval: true with your LLM credentials to generate a unique per-chunk context string for every chunk. Each context describes the document identity, section identity, and specific entities in that chunk — then prepends it to the chunk text before embedding. This technique, proven by Anthropic to boost retrieval accuracy by 35–50%, is billed at $0.0010 per successfully enriched chunk.


from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()  # reads SCRAPEDATSHI_API_KEY from env

result = client.pipeline.chunk_url(
    "https://example.com/article",
    # Optional: contextual retrieval (Basic tier+)
    # contextual_retrieval=True,
    # llm_provider="openai",
    # llm_api_key=os.getenv("OPENAI_API_KEY"),
)

print(f"Chunks: {result.total_chunks}  |  Source: {result.source}")
for chunk in result.chunks:
    print(f"  [{chunk.token_estimate} tokens] {chunk.content[:100]}...")

Automatically discover and scrape an entire domain — returning a structured dataset of every page's content ready for vector databases. One API call replaces hundreds of individual scrape requests.

🗺️ Sitemap Mode (Basic tier+)

Reads the domain's sitemap.xml to discover URLs. Structured, predictable, and respects robots.txt. Best for documentation sites and structured content.

🕷️ Deep Spider Mode (Pro/Enterprise)

Follows links recursively from the root URL. Works on any site — even those without a sitemap. Use include_pattern to keep it focused.

Endpoint

POST https://www.scrapedatshi.com/v1/crawl

Send a JSON body with Content-Type: application/json.

Request Body (application/json)

Field Type Description
url string Required. Root URL of the domain to crawl.
include_pattern string Only crawl URLs containing this substring (e.g. /docs/). Recommended guardrail.
exclude_pattern string Skip URLs containing this substring (e.g. /blog/).
max_pages int Max pages to crawl. Capped by your tier limit.
selector string Optional CSS selector applied to every page (e.g. article).
chunk bool If true, run each page through the RAG chunker. Default: false.
chunk_size int Target tokens per chunk (if chunk=true). Default: 512.
overlap int Token overlap between chunks (if chunk=true). Default: 50.

Sitemap Mode (Basic tier+)

from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()

# Sitemap mode — reads sitemap.xml, structured and predictable
result = client.pipeline.crawl(
    "https://docs.example.com",
    max_pages=10,
)

print(f"Crawled {result.pages_crawled} pages → {result.total_chunks} chunks")
for chunk in result.chunks:
    print(f"  {chunk.content[:80]}...")

Deep Spider Mode (Pro/Enterprise — follows links, no sitemap needed)

# Spider mode — follows links recursively, works on any site
# Use include_pattern to keep it focused on the right section
result = client.pipeline.crawl(
    "https://example.com",
    max_pages=20,
)

Scrape any URL and extract structured data matching your exact JSON schema — powered by your own LLM. No more brittle CSS selectors that break when a site redesigns. Define the fields you want in plain English and let the LLM do the parsing.

Supports OpenAI, Anthropic, and Google Gemini. You bring your own API key — we handle the scraping and prompt engineering.

Endpoint

POST https://www.scrapedatshi.com/v1/extract

Send a JSON body with Content-Type: application/json.

Request Body (application/json)

Field Type Description
url string Required. The URL to scrape and extract from.
schema object Required. Dict of field names to description strings. e.g. {"price": "number — price in USD"}.
llm_provider string Required. openai, anthropic, or gemini.
llm_api_key string Required. Your LLM provider API key.
llm_model string Required. Check your provider's documentation for available models.
selector string Optional CSS selector to target a specific element before extraction.
js_render bool If true, uses a headless Chromium browser to render JavaScript before scraping. Adds a $0.0050 surcharge.
extract_as_list bool If true, extracts a list of matching items instead of a single object. Use for product listings, article feeds, search results.

Response Shape

{
  "authenticated_user": "your_name",
  "url": "https://example.com/product",
  "selector": null,
  "llm_provider": "openai",
  "llm_model": "gpt-4o-mini",
  "schema_fields": ["title", "price", "in_stock", "description"],
  "field_count": 4,
  "credits_used": 0.0054,
  "credits_remaining": 9.9946,
  "extracted": {
    "title": "Widget Pro 3000",
    "price": 49.99,
    "in_stock": true,
    "description": "The most advanced widget on the market."
  }
}

import os
from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()

result = client.pipeline.extract(
    url="https://example.com/product/widget-pro",
    schema={
        "title": "string — the product name",
        "price": "number — price in USD, no currency symbol",
        "in_stock": "boolean — whether the product is available",
        "description": "string — short product description, 1-2 sentences",
    },
    llm_provider="openai",
    llm_api_key=os.getenv("OPENAI_API_KEY"),
    llm_model="gpt-4o-mini",
)

print(result.extracted)
# → {"title": "Widget Pro", "price": 49.99, "in_stock": True, "description": "..."}
print(f"Cost: ${result.credits_used:.4f}")

Complete the entire RAG ingestion pipeline in a single API call. scrapedatshi scrapes the URL, chunks the content, generates vector embeddings via your embedding provider, and upserts directly into your vector database — zero additional code required.

Embedding: OpenAI, Cohere, Gemini, Mistral, Voyage AI, or Ollama (local). Vector DB: Pinecone, Qdrant, Supabase, Weaviate, MongoDB Atlas, Azure Cosmos DB, ChromaDB, or LanceDB. You bring your own keys.

Endpoint

POST https://www.scrapedatshi.com/v1/sync

Send a JSON body with Content-Type: application/json.

Request Body (application/json)

Field Type Description
url string Required. The URL to scrape, chunk, embed, and inject.
embedding object Required. Embedding provider config.
provider — Required. One of: openai, cohere, gemini, mistral, voyage, ollama.
api_key — Required (pass "" for Ollama).
model — Required. Check your provider's docs for available models.
endpoint — Required for Ollama only. Public ngrok HTTPS URL (e.g. https://abc123.ngrok-free.app).
vector_db object Required. Vector DB provider config.
provider — Required. One of: pinecone, qdrant, supabase, weaviate, mongodb, azure_cosmos, azure_cosmos_mongo, chroma, lancedb.
Additional fields vary by provider — see the Raw REST example below.
selector string Optional CSS selector to target a specific element before chunking (e.g. article).
chunk_size int Target tokens per chunk. Default: 512. Range: 64–4096.
overlap int Token overlap between consecutive chunks. Default: 50.
max_chunks int Maximum chunks to embed and upsert. Default: 200, max: 500.
js_render bool If true, uses a headless Chromium browser to render JavaScript before scraping. Adds a $0.0050 surcharge per fetch.
contextual_retrieval bool If true, generates per-chunk LLM context before embedding (RAG 2.0). Requires llm_provider, llm_api_key, and llm_model. Billed at $0.0010 per enriched chunk.
llm_provider / llm_api_key / llm_model string Required when contextual_retrieval=true. LLM provider (openai, anthropic, gemini), your API key, and model name.

Response Shape

{
  "authenticated_user": "your_name",
  "url": "https://docs.example.com/",
  "selector": "article",
  "chunks_created": 47,
  "vectors_upserted": 47,
  "total_tokens_estimated": 24100,
  "embedding_provider": "openai",
  "embedding_model": "text-embedding-3-small",
  "vector_db_provider": "pinecone",
  "metadata": { "title": "...", "author": "...", ... }
}

import os
from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()

result = client.pipeline.sync(
    url="https://docs.example.com/getting-started",
    embedding_provider="openai",
    embedding_api_key=os.getenv("OPENAI_API_KEY"),
    embedding_model="text-embedding-3-small",
    vector_db="pinecone",
    vector_db_config={
        "api_key": os.getenv("PINECONE_API_KEY"),
        "index_host": os.getenv("PINECONE_INDEX_HOST"),  # e.g. https://my-index-xyz.pinecone.io
    },
)

print(f"Upserted {result.vectors_upserted} vectors ({result.total_tokens} tokens)")
print(f"Embedding: {result.embedding_provider}  |  Vector DB: {result.vector_db_provider}")

The full RAG pipeline for entire websites in a single call. AutoRAG crawls a domain (via sitemap or deep spider), chunks every page, generates embeddings, and upserts directly into your vector database. Large sites are automatically split into sequential batches — no manual pagination needed.

Same embedding and vector DB providers as /v1/sync. Supports Contextual Retrieval (RAG 2.0) for per-chunk LLM enrichment before embedding.

🔄 Auto-Batching

When a site has more pages than the per-batch cap (200), AutoRAG automatically splits the job into sequential batches. Each batch is processed independently so the server stays responsive for other users. The response includes auto_batched: true, batches_processed, and batch_size when batching occurs.

Endpoints

POST https://www.scrapedatshi.com/v1/autorag       — Full pipeline (crawl + embed + inject)
POST https://www.scrapedatshi.com/v1/crawl-chunk   — Crawl + chunk only (returns JSON, no VDB)

Key Request Fields (application/json)

Field Type Description
url string Required. Root URL of the domain to crawl.
crawl_mode string "sitemap" (default) or "spider". Sitemap reads sitemap.xml; spider follows links on any site.
max_pages int Max pages to crawl. No hard limit — large jobs are auto-batched. Default: 5.
include_pattern / exclude_pattern string URL substring filters. Use include_pattern to keep the crawl focused on a specific section.
embedding object Required for /v1/autorag. Same shape as /v1/syncprovider, api_key, model.
vector_db object Required for /v1/autorag. Same shape as /v1/syncprovider + provider-specific fields.

Response Shape (/v1/autorag)

{
  "authenticated_user": "your_name",
  "root_url": "https://docs.example.com/",
  "crawl_mode": "sitemap",
  "pages_discovered": 847,
  "pages_crawled": 847,
  "pages_failed": 3,
  "total_chunks": 4231,
  "vectors_upserted": 4231,
  "total_tokens_estimated": 2180000,
  "embedding_provider": "openai",
  "embedding_model": "text-embedding-3-small",
  "vector_db_provider": "pinecone",
  "credits_used": 14.8085,
  "credits_remaining": 35.1915,
  "auto_batched": true,
  "batches_processed": 5,
  "batch_size": 200
}

import os
from scrapedatshi import ScrapedatshiClient

client = ScrapedatshiClient()

# AutoRAG — crawl an entire site and inject into your vector DB
result = client.pipeline.autorag(
    url="https://docs.example.com",
    crawl_mode="sitemap",          # or "spider" for sites without a sitemap
    max_pages=500,                 # large jobs are auto-batched server-side
    include_pattern="/docs/",      # guardrail: only /docs/ pages
    embedding_provider="openai",
    embedding_api_key=os.getenv("OPENAI_API_KEY"),
    embedding_model="text-embedding-3-small",
    vector_db="pinecone",
    vector_db_config={
        "api_key": os.getenv("PINECONE_API_KEY"),
        "index_host": os.getenv("PINECONE_INDEX_HOST"),
    },
)

print(f"Crawled {result.pages_crawled} pages → {result.vectors_upserted} vectors")
if result.auto_batched:
    print(f"Auto-batched: {result.batches_processed} batches of {result.batch_size} pages")

The scrapedatshi MCP server exposes all pipeline tools directly inside Claude Desktop — no code required. Ask Claude to scrape a URL, chunk a site, extract structured data, or run the full AutoRAG pipeline, and it calls the API on your behalf.

🐍 Python SDK

For developers building pipelines in code. Full typed API, sync + async, IDE autocomplete.

PyPI: scrapedatshi →
🤖 Claude MCP

For Claude Desktop users. Talk to Claude naturally — it handles the API calls.

PyPI: scrapedatshi-mcp →

Installation

pip install scrapedatshi-mcp

Claude Desktop Configuration

Add this to your claude_desktop_config.json:

{
  "mcpServers": {
    "scrapedatshi": {
      "command": "uvx",
      "args": ["--refresh", "scrapedatshi-mcp[all]"],
      "env": {
        "SCRAPEDATSHI_API_KEY": "your-scrapedatshi-api-key"
      }
    }
  }
}

The [all] extra installs all optional LLM and embedding provider SDKs (OpenAI, Anthropic, Gemini, Cohere, Mistral, Voyage AI). Use --refresh to always pull the latest version.

Available Tools in Claude

Tool What it does
scrape_url Scrape any URL to clean Markdown
chunk_file Parse and chunk a local file (PDF, MD, TXT, JSON)
crawl_site Crawl a domain's sitemap and return page content
extract_data Extract structured data from a URL using your LLM
sync_to_vectordb Full pipeline: scrape → chunk → embed → inject
autorag Full pipeline for entire sites: crawl → chunk → embed → inject
verify_provider_key Verify an LLM or embedding API key and list available models

Example Prompts

💬 "Scrape https://example.com/docs and give me a summary"
💬 "Crawl the entire docs.stripe.com site and inject it into my Pinecone index"
💬 "Extract the product name, price, and availability from this URL using my OpenAI key"
💬 "Verify my Anthropic API key and show me the available models"

Extract all tables from a PDF as structured JSON. Each table is an array of rows; each row is an array of cell strings.

Endpoint

POST https://www.scrapedatshi.com/api/pdf/tables

Request Body (multipart/form-data)

Field Type Description
url string URL of the PDF to fetch.
pdf_file file Upload a PDF file directly (max 20 MB).

Response Shape

{
  "authenticated_user": "your_name",
  "source": "https://example.com/report.pdf",
  "table_count": 2,
  "tables": [
    {
      "page": 1,
      "table_index": 1,
      "rows": [
        ["Header 1", "Header 2", "Header 3"],
        ["Row 1 A",  "Row 1 B",  "Row 1 C"],
        ["Row 2 A",  "Row 2 B",  "Row 2 C"]
      ]
    }
  ]
}

The Python SDK wraps the /v1/* pipeline endpoints. For PDF table extraction, use the raw REST example below.

# PDF Tables is a raw REST endpoint — use requests directly.
# See the Raw REST tab for the full example.

# To chunk a PDF file with the SDK instead:
from scrapedatshi import ScrapedatshiClient
client = ScrapedatshiClient()
result = client.pipeline.chunk_file("./report.pdf")
print(f"Got {result.total_chunks} chunks")

Ready to start building?

🚀 Get your API key →