Skip to main content

serpex

Official Python SDK for the Serpex SERP API - Fetch search results in JSON format.

Installation

pip install serpex

Or with poetry:

poetry add serpex

Quick Start

from serpex import SerpexClient

# Initialize the client with your API key
client = SerpexClient('your-api-key-here')

# Search with auto-routing (recommended for simple use cases)
results = client.search({
    'q': 'python tutorial',
    'engine': 'auto'
})

# Or using SearchParams object for type safety
from serpex import SearchParams

params = SearchParams(q='python tutorial', engine='auto')
results = client.search(params)

print(results.results[0].title)

API Reference

SerpexClient

Constructor

SerpexClient(api_key: str, base_url: str = "https://api.serpex.dev")
  • api_key: Your API key from the Serpex dashboard
  • base_url: Optional base URL (defaults to 'https://api.serpex.dev')

Methods

extract(params: ExtractParams | Dict[str, Any]) -> ExtractResponse

Extract content from web pages and convert them to LLM-ready markdown data. Accepts up to 10 URLs per request.

# Basic usage
results = client.extract({
    'urls': [
        'https://example.com',
        'https://httpbin.org'
    ]
})

# With stealth mode and HTML output
results = client.extract({
    'urls': ['https://example.com'],
    'stealth': True,
    'format': 'html'
})

# Using ExtractParams object (type-safe approach)
from serpex import ExtractParams

params = ExtractParams(
    urls=['https://example.com'],
    stealth=True,
    format='html'
)
results = client.extract(params)

Extract Parameters

The ExtractParams dataclass supports extraction parameters:

@dataclass
class ExtractParams:
    # Required: URLs to extract (max 10)
    urls: List[str]

    # Optional: Route through premium unblocker for difficult-to-crawl pages (default: False)
    stealth: bool = False

    # Optional: Output format — 'markdown' (default) or 'html'
    format: str = 'markdown'

Extract Response Format

@dataclass
class ExtractResponse:
    success: bool
    results: List[ExtractResult]
    metadata: ExtractMetadata

@dataclass
class ExtractResult:
    url: str
    success: bool
    markdown: Optional[str] = None
    html: Optional[str] = None         # Populated when format='html'
    stealth: Optional[bool] = None     # Whether stealth mode was used for this result
    error: Optional[str] = None
    status_code: Optional[int] = None

@dataclass
class ExtractMetadata:
    total_urls: int
    processed_urls: int
    successful_crawls: int
    failed_crawls: int
    credits_used: int
    response_time: int
    timestamp: str
    cached_free: Optional[int] = None  # URLs served from cache (no credit charge)

Search Parameters

The SearchParams dataclass supports all search parameters:

@dataclass
class SearchParams:
    # Required: search query
    q: str

    # Optional: Engine selection (defaults to 'auto')
    engine: Optional[str] = 'auto'

    # Optional: also fetch page content (markdown) for top results (default: False)
    include_content: bool = False

    # Optional: number of top results to fetch content for — must be exactly
    # 5 or 10 (default: 5). Only relevant when include_content is True.
    content_results: Literal[5, 10] = 5
Param Type Default Notes
q str Required search query (max 500 chars)
include_content bool False Also fetch page content (markdown) for top results
content_results Literal[5, 10] 5 How many top results to fetch content for; must be exactly 5 or 10

Supported Engines

  • auto: Automatically routes to the best available search engine
  • google: Google's primary search engine
  • bing: Microsoft's search engine
  • duckduckgo: Privacy-focused search engine
  • brave: Privacy-first search engine
  • yahoo: Yahoo search engine
  • yandex: Russian search engine

Response Format

@dataclass
class SearchMetadata:
    number_of_results: int
    response_time: int
    timestamp: str
    credits_used: int
    from_cache: Optional[bool] = None
    status: Optional[str] = None
    # Present only when include_content was requested
    content_requested: Optional[int] = None
    content_delivered: Optional[int] = None

@dataclass
class SearchResult:
    title: str
    url: str
    snippet: str
    position: int
    engine: str
    img_src: Optional[str] = None
    duration: Optional[str] = None
    score: Optional[float] = None
    # Present only when include_content was requested. Best-effort — a
    # failed extraction sets content_error instead of content.
    content: Optional[str] = None
    content_error: Optional[str] = None

@dataclass
class SearchResponse:
    metadata: SearchMetadata
    id: str
    query: str
    engines: List[str]
    results: List[SearchResult]

Error Handling

The SDK raises SerpApiException for API errors:

from serpex import SerpexClient, SerpApiException

try:
    results = client.search(SearchParams(q='test query'))
except SerpApiException as e:
    print(f"API error: {e}")
    print(f"Status code: {e.status_code}")
    print(f"Details: {e.details}")

Examples

Basic Search

results = client.search({
    'q': 'coffee shops near me'
})

Search with Page Content

Fetch page content (markdown) for the top results inline with the search — best-effort, so check each result for content vs content_error.

results = client.search({
    'q': 'best espresso machines 2025',
    'include_content': True,
    'content_results': 10,  # must be exactly 5 or 10
})

print(
    f"Content delivered for {results.metadata.content_delivered}/"
    f"{results.metadata.content_requested} requested results"
)

for result in results.results:
    if result.content:
        print(f"✅ {result.url}: {len(result.content)} chars of markdown")
    elif result.content_error:
        print(f"❌ {result.url}: {result.content_error}")

Extract Web Content to LLM-Ready Data

Extract from a Single URL

# Extract content from one website (markdown, default)
result = client.extract({
    'urls': ['https://example.com']
})

if result.results[0].success:
    print(f"✅ Extracted {len(result.results[0].markdown)} characters")
    print("Markdown content:", result.results[0].markdown[:200] + "...")

# Extract with stealth mode and HTML output
stealth_result = client.extract({
    'urls': ['https://example.com'],
    'stealth': True,
    'format': 'html'
})

if stealth_result.results[0].success:
    print("HTML content:", stealth_result.results[0].html[:200])

Extract from Multiple URLs (up to 10 at once)

# Extract content from multiple websites (up to 10 URLs)
extract_results = client.extract({
    'urls': [
        'https://example.com',
        'https://httpbin.org',
        'https://github.com'
    ]
})

print(f"Successfully extracted {extract_results.metadata.successful_crawls} pages")
print(f"Total credits used: {extract_results.metadata.credits_used}")

for result in extract_results.results:
    if result.success:
        print(f"✅ {result.url}: {len(result.markdown)} characters")
        # Use result.markdown for LLM processing
    else:
        print(f"❌ {result.url}: {result.error}")

Sample Response

# Example response structure
{
    'success': True,
    'results': [
        {
            'url': 'https://example.com',
            'success': True,
            'markdown': '# Example Domain\n\nThis domain is for use in...',
            'stealth': False,
            'status_code': 200
        }
    ],
    'metadata': {
        'total_urls': 1,
        'processed_urls': 1,
        'successful_crawls': 1,
        'failed_crawls': 0,
        'credits_used': 3,
        'cached_free': 0,
        'response_time': 255,
        'timestamp': '2025-11-13T10:30:00.000Z'
    }
}

Using ExtractParams Object

from serpex import ExtractParams

params = ExtractParams(urls=[
    'https://example.com',
    'https://httpbin.org'
])
results = client.extract(params)

Requirements

  • Python 3.8+
  • requests

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

serpex-2.9.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

serpex-2.9.0-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file serpex-2.9.0.tar.gz.

File metadata

  • Download URL: serpex-2.9.0.tar.gz
  • Upload date:
  • Size: 9.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for serpex-2.9.0.tar.gz
Algorithm Hash digest
SHA256 6507fea2477634bb1fbe8abe0005cebaf226a8cf344600df385d565254c52113
MD5 733d8db426889e6870abade914a03d66
BLAKE2b-256 0a3ca97b92062737822c33dcbc94be71eaa0d9316304a9d3c0012c0beb3d10c7

See more details on using hashes here.

File details

Details for the file serpex-2.9.0-py3-none-any.whl.

File metadata

  • Download URL: serpex-2.9.0-py3-none-any.whl
  • Upload date:
  • Size: 9.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for serpex-2.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0b2a5cdaa48a63ed8ada8ad2951db65d00a814258e611d807995a2bf81d76c49
MD5 b67252bd073127ddaabe12d204c8b8d5
BLAKE2b-256 f974b8dc8d559c78088aeab1fcdb49d39034a784de4ab0a0183e00131b3eb116

See more details on using hashes here.

Release history Release notifications | RSS feed

2.10.0

2 files

This release

2.9.0 This release

2 files

2.8.1

2 files

2.8.0

2 files

2.7.0

2 files

2.6.0

2 files

2.5.0

2 files

2.3.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

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