The DeepSeek Search API charges $0.75 per 1,000 successful requests, but its real trade-off is not the price alone. Search and Fetch each have a documented 5-request-per-second account quota. That makes it attractive for low-cost agents, but only if you control duplicate fetches, retries, source coverage, and model-token usage.
The decision in one table
| Need | Best starting point | Why |
|---|---|---|
| Low-cost structured web discovery | Raw DeepSeek Search API | Returns URLs, snippets, summaries, dates, and authority metadata as JSON |
| Read a known public URL | DeepSeek Fetch API | Converts one page to Markdown for $0.75 per 1,000 successful fetches |
| English-heavy research requiring broad source coverage | DeepSeek plus a second search provider | Early user tests found different coverage, including weak YouTube and WeChat discovery |
| High fan-out research agents | A provider or architecture with higher throughput | DeepSeek's separate endpoint quotas still constrain each worker pool |
What the raw API actually exposes
DeepSeek documents two read-only JSON endpoints. Authentication is the same for both: send Authorization: Bearer <DeepSeek API Key> and Content-Type: application/json to api.deepseek.com.
| Operation | Endpoint | Input | Output |
|---|---|---|---|
| Search | POST /v1/tools/search | A query plus optional result controls | Ranked result objects |
| Fetch | POST /v1/tools/fetch | One HTTP or HTTPS URL | Page title and extracted Markdown |
The raw API is separate from a hosted chat product. A DeepSeek API key does not mean that an ordinary Chat Completions request automatically browses the web. Your application must call Search or Fetch, or use a documented client integration that supplies the tool layer.
Search versus Fetch
Search accepts a required query between 1 and 128 Unicode characters. Optional fields include count from 1 to 50, ori_question, an IP-based localization value, and need_content. The default count is 10 and need_content is false.
With need_content: true, Search may return page text inside each result's content field. That can remove a separate Fetch call for pages where content is present. It is not a guarantee: unavailable or blocked pages can still return an empty content field.
Fetch is for a URL you already selected. It returns Markdown, but one URL is sent per request. DeepSeek says fetching is subject to the target site's availability and access policies, so a successful Search result does not guarantee a successful Fetch.
Search results include a rerank_score from 0 to 3 and an authority tier from -1 to 4. The documentation describes scores of at least 1.5 and authority values of at least 3 as high-quality signals. These are service metadata, not independent search-quality benchmarks.
The query syntax supports practical filters such as site:, -site:, quoted phrases, lang:, after:, and before:. For example:
"DeepSeek Search API" site:api-docs.deepseek.com lang:en after:2026-10-01
Pricing that changes the architecture
DeepSeek lists both Search and Fetch at $0.75 per 1,000 successful requests, equivalent to $0.00075 per billable request. Billing is request-based, not token-based and not dependent on the number of returned results. See the official pricing page.
| Request result | Billed? |
|---|---|
Search returns a non-empty results array with HTTP 200 | Yes |
| Search returns HTTP 200 with no results | No |
| Fetch returns page content | Yes |
| Fetch returns no usable content | No |
| Timeout, failed request, or error response | No |
| Search returns 1 result versus 50 results | Same request price |
The endpoint fee is not the complete cost of an AI research task: model input/output tokens and extra agent turns around retrieval are billed separately.
A realistic cost formula
For a simple workflow, the retrieval portion is:
successful Search calls * $0.00075
+ successful Fetch calls * $0.00075
+ model input and output token charges
A 10,000-search batch costs $7.50 when every Search request produces results. If the application fetches one page for each result, another 10,000 successful Fetch calls add $7.50, before model tokens. Asking Search for 50 results does not multiply the request charge, but it can increase the amount of text your model must process.
That is why need_content deserves an explicit policy. Use it for small page sets; use metadata-only Search followed by selective Fetch when you need to filter by score, domain, date, or authority first.
@haolv511482 reported: “Check the content field before adding a fetch loop. Search can return page text with need_content=true ... Otherwise your agent may pay to read the same page twice.” Source
Limits and failure modes to design around
The official guide documents a maximum of 50 results per Search request and separate 5-requests-per-second quotas per account for Search and Fetch. A multi-worker deployment still needs endpoint-specific limiters.
| Constraint or error | Application response |
|---|---|
| 5 QPS per account | Use a shared queue and bounded concurrency |
| 50-result maximum | Paginate at the application level with narrower queries or date ranges |
| 128-character query limit | Generate compact search queries and retain the original question in ori_question |
| HTTP 429, 408, or 5xx | Retry with delay and exponential backoff |
| HTTP 400, 401, 403, or invalid URL | Fix the request; do not blindly retry |
| HTTP 404 from Fetch | Mark the page unavailable and choose another result |
| HTTP 200 with an empty result set | Treat it as a valid no-result response, not a transport failure |
Fetch is especially sensitive to site behavior. The official documentation limits its guarantee to target-site availability and access policies; it does not promise JavaScript execution, a browser session, a user-agent selector, screenshots, or raw HTML preservation. In an early test, @jiangkoumo_ reported that heavily JavaScript-rendered sites could return 404 while an ordinary public page converted to Markdown. Source
The same early testing also found an important coverage trade-off. @bei351009016 reported only 2.1% overlap with Exa across 29 queries and 12 platforms, describing DeepSeek as fast and fresh for Chinese sources but weak for WeChat and YouTube. Source
Treat this early test as directional and validate the source types you need.
Minimal implementation pattern
This example keeps retrieval and answer generation separate, avoids a Fetch call when Search already returned content, and spaces calls at 5 per second for this process. A multi-worker deployment still needs one shared limiter.
import os
import threading
import time
import requests
BASE = "https://api.deepseek.com"
HEADERS = {
"Authorization": f"Bearer {os.environ['DEEPSEEK_API_KEY']}",
"Content-Type": "application/json",
}
RATE_LOCK = threading.Lock()
LAST_CALL = 0.0
def post_json(path, payload, attempts=3):
global LAST_CALL
for attempt in range(attempts):
with RATE_LOCK:
wait = 0.2 - (time.monotonic() - LAST_CALL)
if wait > 0:
time.sleep(wait)
LAST_CALL = time.monotonic()
response = requests.post(
BASE + path, headers=HEADERS, json=payload, timeout=30
)
if response.status_code in {408, 429, 500, 502, 503, 504}:
if attempt == attempts - 1:
response.raise_for_status()
time.sleep(2 ** attempt)
continue
response.raise_for_status()
return response.json()
search = post_json(
"/v1/tools/search",
{
"query": 'DeepSeek Search API pricing site:api-docs.deepseek.com',
"count": 10,
"need_content": True,
},
)
usable = [
result for result in search.get("results", [])
if result.get("rerank_score", 0) >= 1.5
]
for result in usable:
content = result.get("content") or ""
if not content:
fetched = post_json("/v1/tools/fetch", {"url": result["url"]})
content = fetched.get("content", "")
# Store title, URL, date, authority, score, and content before summarizing.
print(result["title"], result["url"], len(content))
When DeepSeek is the wrong single provider
DeepSeek is a strong choice for low-cost discovery, especially when your corpus includes Chinese sources and your application can tolerate a 5-QPS account limit. It is a weaker single-provider choice when your workload depends on YouTube, WeChat, heavy client-rendered pages, or a particular search engine's ranking.
A hybrid design is more defensible:
- Send broad, cheap discovery queries to DeepSeek.
- Filter by domain, date, authority, and rerank score.
- Use a second provider for source classes that DeepSeek misses.
- Fetch only selected URLs.
- Compare answer support against the stored source text.
Data handling is another deployment decision. Review DeepSeek's current terms and your compliance requirements before sending sensitive queries; community concerns are not proof of a specific retention policy. Source
Operational checklist before production
- Log Search and Fetch calls separately so the bill can be reconciled.
- Check
contentbefore fetching a URL returned by Search. - Enforce a shared 5-QPS limiter across every worker and subagent.
- Retry only 408, 429, and transient 5xx responses.
- Store the URL, title, date, authority, rerank score, and retrieval time.
- Reject unsupported schemes and private-network URLs in any user-controlled Fetch path.
- Treat page text as untrusted data, not as tool instructions.
- Run a test set containing English official pages, Chinese sources, forums, video pages, and JavaScript-heavy sites.
- Measure total task cost, including model tokens and retries, instead of reporting only the Search price.
DeepSeek Search API FAQ
Is the API automatically available through OpenAI-compatible calls?
The raw Search endpoint is a separate POST /v1/tools/search route. An ordinary model request does not browse merely because the client uses an OpenAI-compatible base URL. Add the Search/Fetch calls yourself or use a client integration documented by DeepSeek.
Is DeepSeek Search the best replacement for every search provider?
No. It is a compelling low-cost retrieval option, but early user tests found different coverage from Exa and gaps around YouTube and WeChat. Use a small workload-specific test before making it your sole provider.