Serpex

Quickstart

Make your first Serpex search and extract request in under 5 minutes.

Get your API key

Sign in at app.serpex.dev, then go to API Keys in the sidebar and create a key. It starts with sk_.

You start with 200 free credits — no credit card required.

POST /api/search with your query. Only q is required.

curl -X POST https://api.serpex.dev/api/search \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"q": "best practices for REST API design"}'
import { SerpexClient } from "serpex";

const client = new SerpexClient("sk_your_api_key");

const result = await client.search({
  q: "best practices for REST API design",
});

console.log(result.results[0].title);
console.log(result.metadata.credits_used); // 1 for a fresh result, 0 if cached
from serpex import SerpexClient

client = SerpexClient("sk_your_api_key")

result = client.search({"q": "best practices for REST API design"})

print(result.results[0].title)
print(result.metadata.credits_used)  # 1 for a fresh result, 0 if cached

Response:

{
  "query": "best practices for REST API design",
  "results": [
    {
      "title": "RESTful API Design Best Practices",
      "url": "https://example.com/rest-api-best-practices",
      "snippet": "A comprehensive guide to designing clean, scalable REST APIs...",
      "position": 1,
      "engine": "duckduckgo"
    },
    {
      "title": "Top 10 REST API Design Tips",
      "url": "https://example.com/api-design-tips",
      "snippet": "Follow these guidelines to build APIs your consumers will love...",
      "position": 2,
      "engine": "duckduckgo"
    }
  ],
  "metadata": {
    "number_of_results": 10,
    "credits_used": 1,
    "from_cache": false,
    "status": "success",
    "response_time": 1420
  }
}

Extract content from a URL

POST /api/crawl fetches one or more pages and returns clean content. Up to 10 URLs per request.

curl -X POST https://api.serpex.dev/api/crawl \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://en.wikipedia.org/wiki/Representational_state_transfer"],
    "format": "markdown"
  }'
const extracted = await client.extract({
  urls: ["https://en.wikipedia.org/wiki/Representational_state_transfer"],
  format: "markdown",
});

const page = extracted.results[0];
if (page.success) {
  console.log(page.markdown); // clean markdown ready for your LLM
}
console.log(extracted.metadata.credits_used); // 1 per URL crawled
extracted = client.extract({
    "urls": ["https://en.wikipedia.org/wiki/Representational_state_transfer"],
    "format": "markdown",
})

page = extracted.results[0]
if page.success:
    print(page.markdown)  # clean markdown ready for your LLM

print(extracted.metadata.credits_used)  # 1 per URL crawled

Response:

{
  "results": [
    {
      "url": "https://en.wikipedia.org/wiki/Representational_state_transfer",
      "success": true,
      "markdown": "# Representational state transfer\n\nRepresentational state transfer (REST) is a software architectural style...",
      "status_code": 200
    }
  ],
  "metadata": {
    "successful_crawls": 1,
    "failed_crawls": 0,
    "credits_used": 1,
    "cached_free": 0
  }
}

For pages protected by anti-bot systems (DataDome, heavy JS challenges, etc.), add "stealth": true to your request. Stealth mode costs 5 credits per URL instead of 1.

Check your credit usage

Always read metadata.credits_used in the response — it tells you exactly what was charged for that request.

  • credits_used: 0 — result came from your organization's cache (free repeat within ~5 minutes).
  • credits_used: 1 — fresh search or normal crawl URL.
  • credits_used: 5 — stealth crawl URL.
  • Errors and empty results are never charged.

Next steps

On this page