DuckDuckGo Search API · source-payload endpoint
DuckDuckGo Search API for controlled SERP capture.
Set a query and documented DuckDuckGo filters, then receive a JSON envelope containing request metadata and the source SERP HTML payload. Your application owns extraction, validation, and schema maintenance.
Server-side GET request · engine=duckduckgo · Discuss your source-data workflow
- Focused search controls Query, locale, interface, safety, time
- Source preserved SERP HTML carried in JSON
- Ownership explicit Your extractor, schema, and validation
- Context attached Request metadata beside payload
kl en_US
kad en_US
kp -1
moderate
A clear handoff
Capture the source response without blurring who owns the data model.
WebScrapingAPI operates the documented DuckDuckGo request path. Your application receives the source payload and decides how to extract, validate, version, store, and use it.
01
Constrain the observation
Keep the query, locale, interface language, safe-search level, time range, and device beside each capture.
02
Retain the source
Receive the source SERP HTML payload inside a JSON envelope rather than assuming a fixed downstream schema.
03
Design your extractor
Select only the fields your workflow needs and validate them against representative payloads.
04
Version layout changes
Treat extraction rules and record schemas as application code that your team tests and maintains.
WebScrapingAPI Documented request execution
Response boundary Metadata + source SERP HTML
Your application Extraction + schema maintenance
DuckDuckGo web search
A focused endpoint for controlled source-SERP observations.
Use the DuckDuckGo engine for web search requests with the documented filter family. Validate actual payloads for the query combinations your product depends on.
Capture scope
Query context in, source page payload out.
The envelope keeps submitted-search metadata adjacent to the DuckDuckGo result payload so your pipeline can retain the provenance it needs.
Locale
Country and language
Scope the search with a documented combined locale value.
Presentation
Interface language
Set the language used by DuckDuckGo controls and labels.
Policy
Safe search
Choose a documented safe-search level for the request.
Recency
Time range
Request a documented day, week, month, or year window, or omit the filter.
Presentation
Device
Select a documented device context for the requested result page.
Coverage boundary: DuckDuckGo can change the fields and markup exposed by its page. Test representative payloads and keep extraction assumptions inside a versioned customer-owned consumer.
Documented filter set
Make the search context explicit before you compare captures.
Begin with the required query. Add only the optional DuckDuckGo filters that belong to the observation you intend to reproduce.
q Required
Search query
Provide the terms DuckDuckGo should search and URL-encode spaces or special characters.
kl Optional
Country + language
Use a documented combined locale code, such as en_US, when the request needs that context.
kad Optional
Interface language
Choose the documented language for DuckDuckGo controls and labels.
kp Optional
Safe-search level
Set on, moderate, or off with the documented numeric value.
df Optional
Time range
Limit results to the past day, week, month, or year, or omit the filter for any time.
device Optional
Device context
Select a documented device value when the requested presentation context matters.
Parameter source of truth Confirm accepted values before production use.
Source-payload response
Treat the JSON envelope as a transport boundary—not your final record model.
The endpoint response is a JSON envelope containing request metadata and the source SERP HTML payload. Your application owns extraction, validation, and schema maintenance.
Documented shape
Metadata beside the payload
JSON
{
"search_parameters": {
"search_engine": "duckduckgo",
"query": "privacy research"
},
"search_results": "<html>...source SERP HTML...</html>"
}Field presence and source markup can change. Store and inspect only what your workflow needs.
Consumer contract
Your team defines the stable layer.
Inspect
Check the HTTP outcome and expected envelope fields.
Extract
Read the elements required by your downstream use case.
Validate
Distinguish absent content, changed markup, and failed extraction.
Version
Record extractor and schema versions with derived data.
Ownership rule
WebScrapingAPI returns the documented envelope. Your application owns any extraction from the source SERP HTML payload and the maintenance of every downstream field contract.
Request to maintained record
Build the capture and extraction lifecycle as separate stages.
Keeping the endpoint response separate from your business schema makes ownership, validation, and layout-change handling easier to reason about.
- 01
Define context
Select the query and only the documented filters required by the observation.
- 02
Send and validate
Call server-side, inspect the HTTP status, and confirm the expected source-payload envelope.
- 03
Extract and version
Apply your tested rules, validate required fields, and attach your schema version.
Integration
Start with one DuckDuckGo request and an explicit failure path.
Keep credentials server-side, URL-encode request values, set a bounded timeout, inspect unsuccessful HTTP states, and validate the envelope before extraction.
Request brief
Test the context your consumer will maintain.
Begin with one representative query and a small, documented filter set. Save the source payload separately from derived records while the extractor is under test.
- Secret
WSA_API_KEYstays server-side- Engine
engine=duckduckgo- Filter example
kl=en_US- Consumer
- Check status, envelope, then source
using System;
using System.Net;
using System.Net.Http;
var rawApiKey = Environment.GetEnvironmentVariable("WSA_API_KEY");
if (string.IsNullOrWhiteSpace(rawApiKey)) {
throw new InvalidOperationException("WSA_API_KEY is required");
}
var key = WebUtility.UrlEncode(rawApiKey);
var url = "https://serpapi.webscrapingapi.com/v2" +
"?api_key=" + key + "&engine=duckduckgo" +
"&q=privacy%20research&kl=en_US&kad=en_US" +
"&kp=1&df=w&device=desktop";
using var client = new HttpClient {
Timeout = TimeSpan.FromSeconds(120)
};
var response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());: "${WSA_API_KEY:?WSA_API_KEY is required}"
curl --get --fail-with-body --max-time 120 \
"https://serpapi.webscrapingapi.com/v2" \
--data-urlencode "api_key=$WSA_API_KEY" \
--data-urlencode "engine=duckduckgo" \
--data-urlencode "q=privacy research" \
--data-urlencode "kl=en_US" \
--data-urlencode "kad=en_US" \
--data-urlencode "kp=1" \
--data-urlencode "df=w" \
--data-urlencode "device=desktop"package main
import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
)
func main() {
apiKey := os.Getenv("WSA_API_KEY")
if apiKey == "" { panic("WSA_API_KEY is required") }
endpoint, err := url.Parse(
"https://serpapi.webscrapingapi.com/v2?engine=duckduckgo&q=privacy%20research",
)
if err != nil { panic(err) }
query := endpoint.Query()
query.Set("api_key", apiKey)
query.Set("kl", "en_US")
query.Set("kad", "en_US")
query.Set("kp", "1")
query.Set("df", "w")
query.Set("device", "desktop")
endpoint.RawQuery = query.Encode()
client := &http.Client{Timeout: 120 * time.Second}
response, err := client.Get(endpoint.String())
if err != nil { panic(err) }
defer response.Body.Close()
if response.StatusCode >= 400 {
panic(fmt.Sprintf("API status %d", response.StatusCode))
}
body, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
fmt.Println(string(body))
}import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
public final class DuckDuckGoExample {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("WSA_API_KEY");
if (apiKey == null || apiKey.isBlank()) {
throw new IllegalStateException("WSA_API_KEY is required");
}
String key = URLEncoder.encode(apiKey, StandardCharsets.UTF_8);
String url = "https://serpapi.webscrapingapi.com/v2" +
"?api_key=" + key + "&engine=duckduckgo" +
"&q=privacy%20research&kl=en_US&kad=en_US" +
"&kp=1&df=w&device=desktop";
var request = HttpRequest.newBuilder(URI.create(url))
.timeout(Duration.ofSeconds(120)).GET().build();
var response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException("API status " + response.statusCode());
}
System.out.println(response.body());
}
}const apiKey = process.env.WSA_API_KEY;
if (!apiKey) throw new Error("WSA_API_KEY is required");
const parameters = new URLSearchParams({
api_key: apiKey,
"engine": "duckduckgo",
"q": "privacy research",
kl: "en_US",
kad: "en_US",
kp: "1",
df: "w",
device: "desktop",
});
const response = await fetch(
"https://serpapi.webscrapingapi.com/v2?" + parameters,
{ signal: AbortSignal.timeout(120_000) }
);
if (!response.ok) {
throw new Error("API status " + response.status);
}
console.log(await response.json());<?php
$apiKey = getenv("WSA_API_KEY");
if ($apiKey === false || $apiKey === "") {
throw new RuntimeException("WSA_API_KEY is required");
}
$endpoint = "https://serpapi.webscrapingapi.com/v2?engine=duckduckgo&q=privacy%20research";
$parameters = http_build_query([
"api_key" => $apiKey,
"kl" => "en_US",
"kad" => "en_US",
"kp" => "1",
"df" => "w",
"device" => "desktop",
]);
$client = curl_init($endpoint . "&" . $parameters);
curl_setopt_array($client, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 120,
]);
$body = curl_exec($client);
$status = curl_getinfo($client, CURLINFO_RESPONSE_CODE);
$error = curl_error($client);
curl_close($client);
if ($body === false) throw new RuntimeException($error);
if ($status >= 400) {
throw new RuntimeException("API status " . $status);
}
echo $body;import os
import requests
api_key = os.environ.get("WSA_API_KEY")
if not api_key:
raise RuntimeError("WSA_API_KEY is required")
response = requests.get(
"https://serpapi.webscrapingapi.com/v2",
params={
"api_key": api_key,
"engine": "duckduckgo",
"q": "privacy research",
"kl": "en_US",
"kad": "en_US",
"kp": "1",
"df": "w",
"device": "desktop",
},
timeout=120,
)
response.raise_for_status()
print(response.json())require "net/http"
require "uri"
api_key = ENV["WSA_API_KEY"]
raise "WSA_API_KEY is required" if api_key.nil? || api_key.empty?
uri = URI("https://serpapi.webscrapingapi.com/v2?engine=duckduckgo&q=privacy%20research")
parameters = URI.decode_www_form(uri.query)
parameters << ["api_key", api_key]
parameters << ["kl", "en_US"]
parameters << ["kad", "en_US"]
parameters << ["kp", "1"]
parameters << ["df", "w"]
parameters << ["device", "desktop"]
uri.query = URI.encode_www_form(parameters)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 10
http.read_timeout = 120
response = http.get(uri.request_uri)
unless response.is_a?(Net::HTTPSuccess)
raise "API status #{response.code}"
end
puts response.bodySource-first use cases
Use controlled captures where your team needs its own extraction contract.
The source payload is an input, not a finished decision. Preserve request context and extractor versions before comparing or operationalizing derived data.
Search observation
Controlled visibility research
Capture comparable DuckDuckGo source pages, then derive the fields and quality states your monitoring model requires.
Explore SERP monitoring →
Market research
Source and topic review
Retain source evidence for query groups and apply your own classification, review, and schema rules.
Explore market research →
Brand visibility
Domain and mention checks
Extract approved signals from controlled payloads while keeping interpretation and escalation with your application.
Explore brand protection →
Data contract
Versioned SERP records
Define the schema, provenance, validation states, and retention policy required beyond request-time capture.
Review search data →
Product choice
Choose by how much of the source-to-schema workflow you want to own.
DuckDuckGo Search API handles the documented engine request and source-payload envelope. Adjacent products shift responsibility toward access infrastructure or managed data delivery.
Proxy infrastructure
Your team builds the search client, retrieval logic, extraction, and response model.
Scraper API
Send an eligible public page URL and own the complete extraction and schema layer.
DuckDuckGo Search API
Send documented search context and receive metadata plus source SERP HTML inside a JSON envelope.
Managed Data
Scope an agreed query set, cadence, schema, quality process, and delivery with WebScrapingAPI.
Production evaluation
Validate payload fit before selecting a plan.
Test ordinary, localized, time-filtered, empty, changed-layout, and unsuccessful cases. Current pricing and plan descriptions remain the commercial source of truth.
Evaluation matrix
Count contexts and maintenance work together.
Illustrative workload formula
Queries × Filter sets × Run frequency + Extractor tests
This is an evaluation model, not a billing formula. Include source retention, schema validation, and layout-change handling in your production design.
Go-live questions
- Context
Which filter combinations matter?
- Contract
Which source fields must be present?
- Quality
How are markup changes detected?
- Recovery
Which failures may be retried?
- Ownership
Who maintains extractor and schema?
FAQ
DuckDuckGo Search API questions for a grounded evaluation.
Use the current documentation and representative source payloads as the implementation source of truth.
What does DuckDuckGo Search API return?
The endpoint returns a JSON envelope containing request metadata and the source SERP HTML payload. It does not define your downstream record schema; your application owns extraction and schema maintenance.
Who owns extraction when the DuckDuckGo layout changes?
Your team owns extraction rules, validation, and schema maintenance for the source SERP HTML payload. When DuckDuckGo changes its page, test your extractor against representative responses before promoting changes.
Which DuckDuckGo filters can I control?
The documented controls used on this page are q for the query, kl for country and language, kad for interface language, kp for safe search, and df for a time range. Omit optional filters you do not need.
Is the source payload already shaped to my schema?
No. The response preserves the source SERP HTML payload inside a JSON envelope. Your application decides which fields to extract, how to model them, and how to version the resulting schema.
How should my application handle unsuccessful requests?
Check the HTTP status before reading the body, retain enough request context to investigate failures, and use bounded retry behavior appropriate to your workflow. Treat response parsing and validation as explicit application steps.
When should I consider Managed Data instead?
Choose the API when your team wants request-time capture and will operate extraction, schema, storage, and scheduling. Consider Managed Data when you want to scope an agreed query set, cadence, schema, quality process, and delivery with WebScrapingAPI.
Your first source capture
Test one DuckDuckGo query against the schema your team intends to maintain.
Start with the documented endpoint, or speak with our team about an agreed managed data workflow.